home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n13.arc / FILECTRL.ASM < prev    next >
Assembly Source File  |  1991-06-12  |  113KB  |  3,259 lines

  1. ;--------------------------------------------------------------------;
  2. ;  FILECTRL * Michael J. Mefford                                     ;
  3. ;                                                                    ;
  4. ;  File viewer and deleter                                           ;
  5. ;--------------------------------------------------------------------;
  6.  
  7. _TEXT          SEGMENT PUBLIC 'CODE'
  8.                ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
  9.  
  10.                ORG     100H
  11. START:         JMP     MAIN
  12.  
  13. ;              DATA AREA
  14. ;              ---------
  15. COLOR_ATTRIBS  STRUC
  16. B              DB      71H                     ;Blue on lt. gray
  17. W              DB      17H                     ;Lt. gray on blue
  18. C              DB      31H                     ;Blue on cyan
  19. I              DB      1FH                     ;White on blue
  20. D              DB      17H                     ;Lt. gray on blue
  21. A              DB      07H                     ;White on black
  22. COLOR_ATTRIBS  ENDS
  23.  
  24. COLOR          COLOR_ATTRIBS  <>
  25.  
  26. COLOR_ATTR     COLOR_ATTRIBS  <>
  27. MONO_ATTR      COLOR_ATTRIBS  <70H, 07H, 70H, 0FH, 0FH, 70H>
  28.  
  29. BORDER_FLAG    DB      0                       ; =1 to disable.
  30.  
  31. ASCEND         EQU     0
  32. DESCEND        EQU     3
  33.  
  34. NAME_SORT      EQU     0                       ;Index into SORT_TABLE               JNZ
  35. EXT_SORT       EQU     4
  36. SIZE_SORT      EQU     8
  37. DATE_SORT      EQU     12
  38. NO_SORT        EQU     0FFH
  39.  
  40. SORT_ORDER     DW      ASCEND                  ;Index into SORTS_CODE (0 or 3)
  41. SORT_INDEX     DW      NAME_SORT               ;Default is Name.
  42.  
  43. COPYRIGHT      DB      "FILECTRL 1.0 Copyright (c) 1991 Michael J. Mefford",CR,LF
  44. FIRST_RIGHTS   DB      "First Published in PC Magazine, July 16, 1991",CR,LF,LF
  45.  
  46. SYNTAX LABEL BYTE
  47. DB  "Syntax: FILECTRL [filespec] [options]",CR,LF,LF
  48.  
  49. DB  "/M [+|-] + = Only include files modified since last backup",CR,LF
  50. DB  "         - = Only include files NOT modified since last backup",CR,LF
  51. DB  "/H = Include Hidden files",CR,LF
  52. DB  "/R = Include Read-only files",CR,LF
  53. DB  "/P date = Only include files ON or Prior date",CR,LF
  54. DB  "/A date = Only include files ON or After date",CR,LF
  55. DB  "   date format = mm/dd/yy",CR,LF
  56. DB  "/W WordStar files; remove high bit",CR,LF
  57. DB  "/N = Sort by Name",CR,LF
  58. DB  "/E = Sort by Extension",CR,LF
  59. DB  "/S = Sort by Size",CR,LF
  60. DB  "/D = Sort by Date",CR,LF
  61. DB  "/O = Sort by Original DOS DIR order",CR,LF
  62. DB  "     default = Sort by Name",CR,LF
  63. DB  "/F   Sort in descending order",CR,LF
  64. DB  "$"
  65.  
  66. SWITCH_CHARS    DB     "MHRP"
  67.                 DB     "AWNE"
  68.                 DB     "SDOF"
  69. SWITCH_LEN      EQU    $ - SWITCH_CHARS
  70.  
  71. SWITCH_DISPATCH DW     SW_MODIFIED, SW_HIDDEN,   SW_READ_ONLY, SW_PRIOR
  72.                 DW     SW_AFTER,    SW_WORDSTAR, SW_NAME,      SW_EXT
  73.                 DW     SW_SIZE,     SW_DATE,     SW_ORIGINAL,  SW_FORMAT
  74.  
  75.  
  76. TAB            EQU     9
  77. CR             EQU     13
  78. LF             EQU     10
  79. CTRL_Z         EQU     26
  80. SPACE          EQU     32
  81. BOX            EQU     254
  82. FF             EQU     12
  83. SHIFT_KEYS     EQU     3
  84. ESC_SCAN       EQU     1
  85. Y_SCAN         EQU     15H
  86. N_SCAN         EQU     31H
  87. F1_SCAN        EQU     3BH
  88. F2_SCAN        EQU     3CH
  89. F3_SCAN        EQU     3DH
  90. F4_SCAN        EQU     3EH
  91. F5_SCAN        EQU     3FH
  92. F6_SCAN        EQU     40H
  93. F7_SCAN        EQU     41H
  94. F8_SCAN        EQU     42H
  95. F9_SCAN        EQU     43H
  96. F10_SCAN       EQU     44H
  97. KB_FLAG        EQU     17H
  98. UP_SCAN        EQU     48H
  99. DOWN_SCAN      EQU     50H
  100. LEFT_SCAN      EQU     4BH
  101. RIGHT_SCAN     EQU     4DH
  102. PGUP_SCAN      EQU     49H
  103. PGDN_SCAN      EQU     51H
  104. BS_SCAN        EQU     0EH
  105. DEL_SCAN       EQU     53H
  106. HOME_SCAN      EQU     47H
  107. END_SCAN       EQU     4FH
  108. ENTER_SCAN     EQU     1CH
  109. TAB_SCAN       EQU     0FH
  110. CTRL_HOME_SCAN EQU     77H
  111. CTRL_END_SCAN  EQU     75H
  112. PLUS1_SCAN     EQU     0DH
  113. PLUS2_SCAN     EQU     4EH
  114. MINUS1_SCAN    EQU     0CH
  115. MINUS2_SCAN    EQU     4AH
  116. SHIFT_F4       EQU     57H
  117. SHIFT_F5       EQU     58H
  118. SHIFT_F6       EQU     59H
  119. SHIFT_F9       EQU     5CH
  120. SHIFT_F10      EQU     5DH
  121. CTRL_F2        EQU     5FH
  122. ALT_F1         EQU     68H
  123. SPACE_SCAN     EQU     39H
  124.  
  125. LEFT_ARROW     EQU     27
  126. RIGHT_ARROW    EQU     26
  127. UP_ARROW       EQU     24
  128. DOWN_ARROW     EQU     25
  129. COMMA          EQU     ","
  130. DECIMAL_POINT  EQU     "."
  131. PLUS_SIGN      EQU     "+"
  132. MINUS_SIGN     EQU     "-"
  133. NOTE           EQU     1046                    ; C
  134.  
  135. PORT_A         EQU     60H
  136.  
  137. TRUE           EQU     1
  138. FALSE          EQU     0
  139.  
  140. WORDSTAR_MASK  DB      0FFH                    ;Storage for WordStar mask.
  141. WORDSTAR       DB      0FFH                    ;7Fh if strip WordStar high bit.
  142. DOS_VERSION    DW      ?
  143. SCREEN_COLOR   DB      ?
  144. BREAK          DB      ?
  145. DEFAULT_DRIVE  DB      ?
  146. WORKING_DRIVE  DB      ?
  147. CURRENT_DIR    DB      66 DUP (?)
  148. WORKING_DIR    DB      66 DUP (?)
  149.  
  150. MATCHING       STRUC
  151. RESERVED       DB      21 DUP (?)
  152. ATTRIBUTE      DB              ?
  153. FILE_TIME      DW              ?
  154. FILE_DATE      DW              ?
  155. SIZE_LOW       DW              ?
  156. SIZE_HIGH      DW              ?
  157. FILE_NAME      DB      13 DUP (?)
  158. MATCHING       ENDS
  159.  
  160. FILE_RECORD    STRUC
  161. MARK           DB              ?
  162. LIST_NAME      DB      12 DUP (?)
  163. LIST_BYTES     DB       8 DUP (?)
  164. LIST_DATE      DB      11 DUP (?)
  165. LIST_TIME      DB       8 DUP (?)
  166. FILE_RECORD    ENDS
  167.  
  168. DIR_PTRS       STRUC
  169. TOP_LOC        DW      ?
  170. BAR_LOC        DW      ?
  171. DIR_PTRS       ENDS
  172.  
  173. DIR_LEVEL      DW      0
  174. DIR_LEVEL_MAX  EQU     20
  175. DIR_POINTERS   DIR_PTRS DIR_LEVEL_MAX DUP (<>)
  176.  
  177. KILOBYTES      =       1024
  178. PARAGRAPH      =       16
  179. FILENAME_SIZE  =       64                      ;64K
  180. FILEBUFF_SIZE  =       8                       ;8K
  181. FILENAME_SEG   DW      ?
  182. FILEBUFF_SEG   DW      ?
  183.  
  184. TEMP_RECORD    EQU     FILENAME_SIZE * KILOBYTES - SIZE FILE_RECORD
  185.  
  186. DTA            DB      SIZE MATCHING DUP (?)
  187. MARK_NAME      DB      ?                       ;Mark part of name.
  188. ASCIIZ_NAME    DB      13 DUP (?)              ;ASCIIZ name.
  189.  
  190. EOF_FLAG       DB      FALSE
  191. CURRENT_PAGE   DW      0
  192. BUFFER_PTR     DW      0
  193. BYTES_READ     DW      ?
  194. FILE_POINTER   DW      ?,?
  195. BUFFER_END     DW      ?
  196. FILE_END       DW      ?,?
  197. PAGE_INDEX     DW      0       ;Index to current page address.
  198. PAGE_MAX       EQU     256 * 2 ; 2 bytes per page
  199. PAGES          DW      PAGE_MAX DUP (?)
  200. FAIL_FLAG      DB      FALSE                   ;True if open failed.
  201. FILE_TYPE      DW      ?     ;Address of file-type handler.
  202. FILE_LINE      DW      ?     ;Address of file-lines handler.
  203. ROW            DW      0
  204. EXEC_EXTENSION DB      "EXECOM"
  205.  
  206.  
  207. CRT_MODE       EQU     49H
  208. CRT_COLS       EQU     4AH
  209. CRT_ROWS       EQU     84H
  210. COLUMNS        DW      ?
  211. CRT_WIDTH      DW      ?
  212. CRT_START      DW      ?
  213. STATUS_REG     DW      3BAH
  214. VIDEO_SEG      DW      0B000H
  215. ROWS           DB      24
  216.  
  217. LISTING_LEN    DW      ?
  218. LISTING_ADDR   DW      0
  219. BAR_ADDR       DW      0
  220. LAST_ADDR      DW      ?
  221.  
  222. FILENAME       DW      ?                       ;Address of filespec to parse.
  223. FILESPEC       DW      ?                       ;Address of parsed filespec.
  224. FILESPEC_END   DW      ?
  225. ATTR           DW      10H                     ;Default = normal files and DIRs.
  226.  
  227. CASE           DB      5FH    ;Capitalize; =FFh if case sensitive.
  228. JB_CODE        EQU     72H
  229. JA_CODE        EQU     77H
  230.  
  231. STATE          DW      LISTING
  232. FILE_CURRENT   DB      FALSE
  233.  
  234. SHORT_NAME     EQU     0
  235. LONG_NAME      EQU     1
  236. FULL_FILE      EQU     2
  237. ZOOM_STATE     DB      SHORT_NAME
  238.  
  239. LCOLUMN_START  DW      ?
  240. LCOLUMN_LEN    DW      ?
  241. LCOLUMN_BAL    DW      ?
  242.  
  243. FCOLUMN_START  DW      ?
  244. FCOLUMN_LEN    DW      ?
  245.  
  246. MENU           LABEL   BYTE
  247. DB " F2 Remove  F3 New  F5 Zoom   F6 Sort "
  248. SORT_MENU1     DB      ?
  249. DB                                       " ("
  250. SORT_MENU2     DB      ?
  251. DB                                         ")  F7 Name  F8 Ext  F9 Size  F10 Date",0
  252. DB " Ctrl-F2 Remove marked   +/- Mark/Unmark   "
  253. DB "Tab, ", LEFT_ARROW, SPACE, RIGHT_ARROW, " select window   Esc to Exit",0
  254.  
  255. PARENT         DB      "Dot-dot is the Parent directory",0
  256. STAR_DOT_STAR  DB      "*.*",0
  257. NOT_ENOUGH     DB      "Not enough memory",CR,LF,LF,"$"
  258. NOT_FOUND      DB      "File not found",CR,LF,LF,"$"
  259. ILLEGAL_PARAM  DB      "Illegal parameter"
  260. CRLFLF         DB       CR,LF,LF,"$"
  261.  
  262. ;              CODE AREA
  263. ;              ---------
  264. KBD_STATUS     DB      ?
  265.  
  266. INT_9          PROC    NEAR
  267.  
  268.                PUSH    AX
  269.                IN      AL,PORT_A
  270.                CMP     AL,0E0H
  271.                JZ      INT_9_END
  272.                CMP     AL,0E1H
  273.                JZ      INT_9_END
  274.                MOV     CS:KBD_STATUS,AL
  275.  
  276. INT_9_END:     POP     AX
  277.                JMP     DWORD PTR CS:OLD9
  278.  
  279. INT_9          ENDP
  280.  
  281. ;----------------------------------------------;
  282. INT_24         PROC    NEAR
  283.  
  284.                STI
  285.                PUSHF
  286.                MOV     CS:FAIL_FLAG,TRUE
  287.                MOV     AL,3
  288.                CMP     CS:DOS_VERSION,300H
  289.                JAE     INT_24_END
  290.                XOR     AL,AL
  291. INT_24_END:    POPF
  292.                IRET
  293.  
  294. INT_24         ENDP
  295.  
  296. ;----------------------------------------------;
  297.  
  298. MAIN           PROC    NEAR
  299.                CLD
  300.  
  301.                MOV     AH,30H
  302.                INT     21H
  303.                XCHG    AL,AH
  304.                MOV     DOS_VERSION,AX
  305.  
  306.                CALL    INSTALL_9
  307.                CALL    INSTALL_24
  308.  
  309.                XOR     BH,BH
  310.                MOV     AH,8
  311.                INT     10H
  312.                MOV     SCREEN_COLOR,AH
  313.  
  314.                MOV     AX,3300H                ;Get Ctrl-Break state.
  315.                INT     21H
  316.                MOV     BREAK,DL
  317.  
  318.                XOR     DL,DL
  319.                MOV     AX,3301H
  320.                INT     21H
  321.  
  322.                MOV     AH,19H                  ;Get default drive so can
  323.                INT     21H                     ; restore after we change it.
  324.                MOV     DEFAULT_DRIVE,AL
  325.                MOV     WORKING_DRIVE,AL
  326.  
  327.                MOV     SI,OFFSET CURRENT_DIR
  328.                CALL    GET_DIR
  329.  
  330.                MOV     BX,OFFSET STACK_POINTER + 15
  331.                MOV     CL,4
  332.                SHR     BX,CL
  333.                ADD     BX,(FILENAME_SIZE+FILEBUFF_SIZE) * (KILOBYTES/PARAGRAPH)
  334.                MOV     AH,4AH                  ;Allocate memory.
  335.                INT     21H
  336.                JNC     SETUP_STACK
  337.                MOV     DX,OFFSET NOT_ENOUGH
  338.                JMP     SHORT ERROR_EXIT          ;If not enough, exit.
  339.  
  340. SETUP_STACK:   MOV     AX,OFFSET STACK_POINTER
  341.                MOV     SP,AX                   ;Set up stack.
  342.                ADD     AX,15
  343.                MOV     CL,4
  344.                SHR     AX,CL
  345.                MOV     CX,DS
  346.                ADD     AX,CX
  347.                MOV     FILENAME_SEG,AX         ;And data segments.
  348.                ADD     AX,FILENAME_SIZE * (KILOBYTES / PARAGRAPH)
  349.                MOV     FILEBUFF_SEG,AX
  350.  
  351.                MOV     DX,OFFSET DTA
  352.                MOV     AH,1AH
  353.                INT     21H
  354.  
  355.                MOV     FILENAME,81H
  356.                CALL    NEW_FILESPEC
  357.                JC      ERROR_EXIT
  358.                CALL    VIDEO_SETUP
  359.                CALL    DISP_DIR
  360.                CALL    INIT_ZOOM
  361.                CALL    DISPLAY_MENU
  362.                CALL    DISP_LISTING
  363.                CALL    DISP_FILE
  364.                JMP     SHORT NEXT_KEY
  365.  
  366. ;************* Main Loop *************;
  367.  
  368. NEXT_KEY:      CALL    GETKEY
  369.                JC      GOOD_EXIT
  370.                CMP     AH,CR
  371.                JNZ     CK_PLUS
  372.                CALL    ENTER
  373.                JMP     NEXT_KEY
  374.  
  375. CK_PLUS:       CMP     AH,"+"
  376.                JZ      MAIN_DISPATCH
  377.                CMP     AH,"-"
  378.                JZ      MAIN_DISPATCH
  379.                CMP     AH,SPACE
  380.                JBE     MAIN_DISPATCH
  381.                CALL    SEARCH
  382.                JMP     NEXT_KEY
  383.  
  384. MAIN_DISPATCH: CALL    [STATE]
  385.                JMP     NEXT_KEY
  386.  
  387. ;----------------------------------------------;
  388.  
  389. ERROR_EXIT:    CALL    PRINT_STRING
  390.                MOV     AL,1
  391.                JMP     SHORT EXIT
  392.  
  393. GOOD_EXIT:     CALL    CLOSE_SCREEN
  394.                XOR     AL,AL                   ;EL=0.
  395.  
  396. EXIT:          PUSH    AX
  397.                CALL    UNINSTALL_9
  398.                CALL    RESTORE_DIR
  399.                MOV     DL,DEFAULT_DRIVE
  400.                MOV     AH,0EH
  401.                INT     21H
  402.  
  403.                MOV     DL,BREAK
  404.                MOV     AX,3301H
  405.                INT     21H
  406.  
  407. TERMINATE:     MOV     DX,OFFSET COPYRIGHT
  408.                CALL    PRINT_STRING
  409.                POP     AX
  410.                MOV     AH,4CH
  411.                INT     21H
  412.  
  413. MAIN           ENDP
  414.  
  415.  
  416. ;**************
  417. ; SUBROUTINES *
  418. ;**************
  419. SEARCH:        PUSH    DS
  420.  
  421.                CMP     STATE,OFFSET LISTING
  422.                JNZ     NO_MATCH
  423.  
  424.                CMP     AH,"a"
  425.                JB      DO_SEARCH
  426.                CMP     AH,"z"
  427.                JA      DO_SEARCH
  428.                AND     AH,5FH
  429.  
  430. DO_SEARCH:     MOV     SI,BAR_ADDR
  431.                MOV     DS,FILENAME_SEG
  432.                CMP     [SI.LIST_NAME],AH
  433.                JZ      NEXT_SEARCH
  434.                XOR     SI,SI
  435.                JMP     SHORT NEXT_SEARCH2
  436.  
  437. NEXT_SEARCH:   ADD     SI,SIZE FILE_RECORD
  438. NEXT_SEARCH2:  CMP     [SI.LIST_NAME],-1
  439.                JZ      NO_MATCH
  440.                CMP     [SI.LIST_NAME],AH
  441.                JNZ     NEXT_SEARCH
  442.  
  443.                POP     DS
  444.                MOV     BAR_ADDR,SI
  445.                MOV     AX,LISTING_LEN
  446.                SHR     AX,1
  447.                MOV     BX,SIZE FILE_RECORD
  448.                MUL     BX
  449.                SUB     SI,AX
  450.                JNC     STORE_MATCH
  451.                XOR     SI,SI
  452. STORE_MATCH:   MOV     LISTING_ADDR,SI
  453.                MOV     FILE_CURRENT,FALSE
  454.                JMP     SHORT SEARCH_END
  455.  
  456. NO_MATCH:      POP     DS
  457.                CALL    BEEP
  458.  
  459. SEARCH_END:    CALL    DISP_LISTING
  460.                CALL    DISP_FILE
  461.                RET
  462.  
  463. ;----------------------------------------------;
  464.  
  465. M_TAB:         JMP     SHORT DO_TOGGLE
  466.  
  467. M_LEFT:        CMP     STATE,OFFSET LISTING
  468.                JZ      TOGGLE_END
  469.                JMP     SHORT DO_TOGGLE
  470.  
  471. M_RIGHT:       CMP     STATE,OFFSET FILE
  472.                JZ      TOGGLE_END
  473.  
  474. DO_TOGGLE:     MOV     BX,OFFSET FILE
  475.                CMP     STATE,OFFSET FILE
  476.                JNZ     CHANGE_STATE
  477.                MOV     BX,OFFSET LISTING
  478.                CMP     ZOOM_STATE,FULL_FILE
  479.                JNZ     CHANGE_STATE
  480.                MOV     AL,LAST_ZOOM
  481.                MOV     ZOOM_STATE,AL
  482. CHANGE_STATE:  MOV     STATE,BX
  483.                CALL    INIT_ZOOM
  484.                CALL    DISP_LISTING
  485.                CALL    DISP_FILE
  486.  
  487. TOGGLE_END:    RET
  488.  
  489. ;----------------------------------------------;
  490.  
  491. L_DISPATCH     DB      UP_SCAN,      DOWN_SCAN,   PGUP_SCAN,    PGDN_SCAN
  492.                DB      HOME_SCAN,    END_SCAN,    PLUS1_SCAN,   PLUS2_SCAN
  493.                DB      MINUS1_SCAN,  MINUS2_SCAN, SPACE_SCAN
  494.  
  495.                DB      TAB_SCAN,     LEFT_SCAN,   RIGHT_SCAN,   SHIFT_F5
  496.                DB      F2_SCAN,      F3_SCAN,     F5_SCAN,      F6_SCAN
  497.                DB      F7_SCAN,      F8_SCAN,     F9_SCAN,      F10_SCAN
  498.                DB      CTRL_F2
  499.  
  500. L_LEN          EQU     $ - L_DISPATCH
  501.  
  502.                DW      LUP,          LDOWN,       LPGUP,        LPGDN
  503.                DW      LHOME,        LEND,        PLUS,         PLUS
  504.                DW      MINUS,        MINUS,       FLOP_MARK
  505.  
  506.                DW      M_TAB,        M_LEFT,      M_RIGHT,      SHIFT_ZOOM
  507.                DW      REMOVE,       NEW_FILE,    ZOOM,         SORT_DIR
  508.                DW      SORT_NAME,    SORT_EXT,    SORT_SIZE,    SORT_DATE
  509.                DW      REMOVE_MARKS
  510.  
  511. ;INPUT: AL=scan code.
  512.  
  513. LISTING:       MOV     DI,OFFSET L_DISPATCH
  514.                MOV     CX,L_LEN
  515.                CALL    DISPATCH
  516.                CALL    DISP_LISTING
  517.                RET
  518.  
  519. ;----------------------------------------------;
  520. ; INPUT: AX=Listing page; BP=BAR_ADDR; DX=LISTING_ADDR; CX=LAST_ADDR.
  521. ; OUTPUT: LISTING_FLAG=TRUE if listing changed.
  522.  
  523. FLOP_MARK:     PUSH    DS
  524.                MOV     DS,FILENAME_SEG
  525.                MOV     AL,DS:[BP]
  526.                CMP     AL,"<"
  527.                JNZ     GET_FLOP
  528.                POP     DS
  529.                JMP     LPAGE_END
  530. GET_FLOP:      MOV     AH,SPACE
  531.                CMP     AL,AH
  532.                JNZ     DO_FLOP
  533.                MOV     AH,RIGHT_ARROW
  534. DO_FLOP:       MOV     DS:[BP],AH
  535.                POP     DS
  536.                JMP     LPAGE_END
  537.  
  538.  
  539. PLUS:          MOV     AL,RIGHT_ARROW         ;Use little right arrow for mark.
  540.                JMP     SHORT PLUSMINUS
  541.  
  542. MINUS:         MOV     AL,SPACE                ;Remove mark with space char.
  543.  
  544. PLUSMINUS:     PUSH    DS
  545.                MOV     DS,FILENAME_SEG
  546.                CMP     DS:BYTE PTR [BP],"<"
  547.                JZ      PLUSMINUS2
  548.                MOV     DS:[BP],AL
  549. PLUSMINUS2:    POP     DS
  550.                JMP     SHORT LDOWN
  551.  
  552.  
  553. LUP:           SUB     BP,SIZE FILE_RECORD     ;Move bar up a line.
  554.                JL      LPAGE_END               ;If < 0, ignore.
  555.                CMP     BP,DX                   ;If bar below top, OK.
  556.                JAE     LPAGE_UPDATE
  557.                SUB     DX,SIZE FILE_RECORD     ;Else, move listing up a line.
  558.                JMP     SHORT LPAGE_UPDATE
  559.  
  560. LDOWN:         ADD     BP,SIZE FILE_RECORD     ;Move bar down a line.
  561.                CMP     BP,CX                   ;If > last line, then ignore.
  562.                JA      LPAGE_END
  563.                ADD     AX,DX                   ;Listing top + page length =
  564.                CMP     BP,AX                   ; listing bottom; If bar below
  565.                JB      LPAGE_UPDATE            ; listing bottom, OK.
  566.                ADD     DX,SIZE FILE_RECORD     ;Else move listing down a line.
  567.                JMP     SHORT LPAGE_UPDATE
  568.  
  569. LPGUP:         SUB     BP,AX                   ;Move bar up a page.
  570.                SUB     DX,AX                   ;Move listing up a page.
  571.                JC      LHOME                   ;If listing < top, then home.
  572.                JMP     SHORT LPAGE_UPDATE      ;Else, OK.
  573.  
  574. LPGDN:         ADD     DX,AX                   ;Move listing down a page.
  575.                CMP     DX,CX                   ;If <= last line, do bar.
  576.                JBE     DO_BAR
  577.                SUB     DX,AX                   ;Else, back to where we were
  578.                MOV     BP,CX                   ; and move bar to last line
  579.                JMP     SHORT LPAGE_UPDATE      ; and update.
  580. DO_BAR:        ADD     BP,AX                   ;Move bar down a page.
  581.                CMP     BP,CX                   ;If bar <= last line, OK.
  582.                JBE     LPAGE_UPDATE
  583.                MOV     BP,CX                   ;Else, move bar to last line.
  584.                JMP     SHORT LPAGE_UPDATE
  585.  
  586. LHOME:         XOR     BP,BP                   ;Move bar to top.
  587.                XOR     DX,DX                   ;Move listing to top.
  588.                JMP     SHORT LPAGE_UPDATE
  589.  
  590. LEND:          MOV     BP,CX                   ;Move bar to last line.
  591.                ADD     CX,SIZE FILE_RECORD     ;Last line + 1 - page length =
  592.                SUB     CX,AX                   ; top of last page.
  593.                CMP     DX,CX                   ;If less than a full page,
  594.                JG      LPAGE_UPDATE            ; then already at last page.
  595.                MOV     DX,CX                   ;Else, move listing to last page.
  596.  
  597. LPAGE_UPDATE:  MOV     BAR_ADDR,BP             ;Store the new bar
  598.                MOV     LISTING_ADDR,DX         ; and listing line start.
  599.                MOV     FILE_CURRENT,FALSE
  600.                MOV     FAIL_FLAG,FALSE
  601.  
  602. LPAGE_END:     RET
  603.  
  604. ;----------------------------------------------;
  605. F_DISPATCH     DB      UP_SCAN,      DOWN_SCAN,   PGUP_SCAN,    PGDN_SCAN
  606.                DB      HOME_SCAN,    END_SCAN
  607.  
  608.                DB      TAB_SCAN,     LEFT_SCAN,   RIGHT_SCAN,   SHIFT_F5
  609.                DB      F2_SCAN,      F3_SCAN,     F5_SCAN,      F6_SCAN
  610.                DB      F7_SCAN,      F8_SCAN,     F9_SCAN,      F10_SCAN
  611.                DB      CTRL_F2
  612.  
  613. F_LEN          EQU     $ - F_DISPATCH
  614.  
  615.                DW      FUP,          FDOWN,       FPGUP,        FPGDN
  616.                DW      FHOME,        FEND
  617.  
  618.                DW      M_TAB,        M_LEFT,      M_RIGHT,      SHIFT_ZOOM
  619.                DW      REMOVE,       NEW_FILE,    ZOOM,         SORT_DIR
  620.                DW      SORT_NAME,    SORT_EXT,    SORT_SIZE,    SORT_DATE
  621.                DW      REMOVE_MARKS
  622.  
  623. FILE:          CMP     FILE_CURRENT,TRUE
  624.                JZ      DISPATCH_FILE
  625.                CALL    OPEN_FILE
  626.                JC      END_FILE
  627.  
  628. DISPATCH_FILE: MOV     DI,OFFSET F_DISPATCH
  629.                MOV     CX,F_LEN
  630.                CALL    DISPATCH
  631. END_FILE:      RET
  632.  
  633. ;----------------------------------------------;
  634. FUP:           CMP     ROW,0
  635.                JNZ     DEC_ROW
  636.                CMP     PAGE_INDEX,0
  637.                JNZ     CK_UP
  638.                JMP     NO_UPDATE
  639. CK_UP:         MOV     AX,LISTING_LEN
  640.                DEC     AX
  641.                MOV     ROW,AX
  642.                JMP     SHORT FPGUP
  643. DEC_ROW:       DEC     ROW
  644.                JMP     FILE_UPDATE
  645.  
  646. ;--------------;
  647. FDOWN:         MOV     AX,ROW
  648.                INC     AX
  649.                MOV     ROW_CNT,AX
  650.                MOV     SI,CURRENT_PAGE
  651.                MOV     BYTE PTR DISPLAY_FLAG,FALSE
  652.                PUSH    DS
  653.                MOV     DS,FILEBUFF_SEG
  654. FDOWN2:        CALL    CS:[FILE_LINE]
  655.                DEC     CS:ROW_CNT
  656.                JNZ     FDOWN2
  657.                POP     DS
  658.                CMP     SI,BUFFER_END
  659.                JNZ     CK_ROW
  660.                CMP     EOF_FLAG,TRUE
  661.                JZ      NO_UPDATE
  662.  
  663. CK_ROW:        MOV     AX,ROW
  664.                INC     AX
  665.                CMP     AX,LISTING_LEN
  666.                JB      INC_ROW
  667.                MOV     ROW,0
  668.                CALL    INC_PAGE
  669.                JMP     SHORT FILE_UPDATE
  670.  
  671. INC_ROW:       INC     ROW
  672.                JMP     SHORT FILE_UPDATE
  673.  
  674. ;--------------;
  675. FPGUP:         CMP     PAGE_INDEX,0
  676.                JNZ     DEC_PG
  677.                MOV     ROW,0
  678.                JMP     SHORT FILE_UPDATE
  679.  
  680. DEC_PG:        MOV     SI,CURRENT_PAGE
  681.                MOV     BX,PAGE_INDEX
  682.                SUB     SI,PAGES[BX]
  683.                JNC     DEC_PG2
  684.                CALL    BACKWARD
  685.                JMP     DEC_PG
  686. DEC_PG2:       SUB     PAGE_INDEX,2
  687.                MOV     CURRENT_PAGE,SI
  688.                JMP     SHORT FILE_UPDATE
  689.  
  690. ;--------------;
  691. FPGDN:         CALL    CK_PAGE
  692.                JC      NO_UPDATE
  693.                JMP     SHORT FILE_UPDATE
  694.  
  695. ;--------------;
  696. FHOME:         CALL    OPEN_FILE
  697.                JMP     SHORT FILE_UPDATE
  698.  
  699. ;--------------;
  700. FEND:          CALL    CK_PAGE
  701.                JNC     FEND
  702.  
  703. FILE_UPDATE:   CALL    DISP_FILE
  704. NO_UPDATE:     RET
  705.  
  706. ;--------------;
  707. CK_PAGE:       CMP     PAGE_INDEX,PAGE_MAX
  708.                JAE     NO_PAGE
  709.  
  710.                MOV     SI,CURRENT_PAGE
  711.                MOV     AX,LISTING_LEN
  712.                MOV     ROW_CNT,AX
  713.                MOV     BYTE PTR DISPLAY_FLAG,FALSE
  714.                PUSH    DS
  715.                MOV     DS,FILEBUFF_SEG
  716. NEXT_PAGE:     CALL    CS:[FILE_LINE]
  717.                DEC     CS:ROW_CNT
  718.                JNZ     NEXT_PAGE
  719.                POP     DS
  720.  
  721.                CMP     SI,BUFFER_END
  722.                JNZ     INC_PAGE
  723.                CMP     EOF_FLAG,TRUE
  724.                JZ      NO_PAGE
  725. INC_PAGE:      MOV     DX,CURRENT_PAGE
  726.                MOV     CURRENT_PAGE,SI
  727.                SUB     SI,DX
  728.                MOV     BX,PAGE_INDEX
  729.                INC     BX
  730.                INC     BX
  731.                MOV     PAGE_INDEX,BX
  732.                MOV     PAGES[BX],SI
  733.                CLC
  734.                JMP     SHORT CK_PAGE_END
  735.  
  736. NO_PAGE:       STC
  737. CK_PAGE_END:   RET
  738.  
  739. ;----------------------------------------------;
  740. ; OUTPUT: CF = 1 if failed.
  741.  
  742. OPEN_FILE:     PUSH    AX
  743.                MOV     BP,BAR_ADDR
  744.                CALL    MAKE_FILENAME
  745.                CMP     MARK_NAME,-1
  746.                JZ      OPEN_FAIL
  747.                CMP     MARK_NAME,"<"
  748.                JNZ     OPEN_FILE2
  749.                MOV     FILE_TYPE,OFFSET SUBDIR
  750.                MOV     FILE_LINE,OFFSET DUMMY_RET
  751.                JMP     SHORT OPEN_GOOD
  752.  
  753. OPEN_FILE2:    MOV     FILE_POINTER[0],0
  754.                MOV     FILE_POINTER[2],0
  755.                MOV     FILE_END[0],-1
  756.                MOV     FILE_END[2],-1          ;Large number to fill buffer.
  757.  
  758.                MOV     CURRENT_PAGE,FILEBUFF_SIZE * KILOBYTES / 2
  759.                MOV     PAGE_INDEX,0
  760.                MOV     ROW,0
  761.  
  762.                XOR     SI,SI
  763.                CALL    READ
  764.                JC      OPEN_FAIL
  765.                CALL    GET_TYPE
  766. OPEN_GOOD:     MOV     FILE_CURRENT,TRUE
  767.                CLC
  768.                JMP     SHORT OPEN_END
  769.  
  770. OPEN_FAIL:     CALL    CLEAR_FILE
  771.                CALL    BEEP
  772.                STC
  773.  
  774. OPEN_END:      POP     AX
  775.                RET
  776.  
  777. ;----------------------------------------------;
  778. ; INPUT:  SI -> Read offset (0 or FILEBUFF_SIZE * KILOBYTES / 2)
  779. ; OUTPUT: CF=1 if read failed.
  780.  
  781. READ:          CMP     FAIL_FLAG,TRUE
  782.                JNZ     READ_NAME
  783.                STC
  784.                JMP     READ_END
  785.  
  786. READ_NAME:     MOV     DX,OFFSET ASCIIZ_NAME
  787.                MOV     AX,3D00H
  788.                INT     21H
  789.                JC      READ_END
  790.                CMP     FAIL_FLAG,TRUE
  791.                STC
  792.                JZ      READ_END
  793.  
  794.                MOV     BX,AX
  795.  
  796.                MOV     DX,FILE_POINTER[0]
  797.                MOV     CX,FILE_POINTER[2]
  798.                MOV     AX,4200H
  799.                INT     21H
  800.                JC      CLOSE
  801.  
  802.                MOV     CX,DX
  803.                MOV     DX,AX
  804.                MOV     AX,FILE_END[0]
  805.                MOV     DI,FILE_END[2]
  806.                SUB     AX,DX
  807.                SBB     DI,CX
  808.                OR      AX,AX
  809.                JNZ     READ1
  810.                OR      DI,DI
  811.                JZ      DO_EOF
  812.  
  813. READ1:         MOV     CX,FILEBUFF_SIZE * KILOBYTES / 2
  814.                OR      DI,DI
  815.                JNZ     READ2
  816.                CMP     CX,AX
  817.                JB      READ2
  818.                MOV     CX,AX
  819.  
  820. READ2:         MOV     DX,SI
  821.                PUSH    DS
  822.                MOV     DS,FILEBUFF_SEG
  823.                MOV     AH,3FH
  824.                INT     21H
  825.                POP     DS
  826.                CMP     FAIL_FLAG,TRUE
  827.                STC
  828.                JZ      CLOSE
  829.  
  830.                MOV     BYTES_READ,AX
  831.                ADD     FILE_POINTER[0],AX
  832.                ADC     FILE_POINTER[2],0
  833.                MOV     DX,AX
  834.                ADD     DX,FILEBUFF_SIZE * KILOBYTES / 2
  835.                MOV     BUFFER_END,DX
  836.                MOV     EOF_FLAG,FALSE
  837.                CMP     AX,FILEBUFF_SIZE * KILOBYTES / 2
  838.                JZ      CLOSE1
  839.  
  840. DO_EOF:        MOV     EOF_FLAG,TRUE
  841.  
  842. CLOSE1:        CLC
  843.  
  844. CLOSE:         PUSHF
  845.                MOV     AH,3EH
  846.                INT     21H
  847.                POPF
  848.  
  849. READ_END:      RET
  850.  
  851. ;----------------------------------------------;
  852. FORWARD:       PUSH    AX
  853.                PUSH    BX
  854.                PUSH    CX
  855.                PUSH    DX
  856.                PUSH    DI
  857.                PUSH    BP
  858.                PUSH    DS
  859.                PUSH    ES
  860.  
  861.                MOV     CX,FILEBUFF_SIZE * KILOBYTES / 2
  862.                SUB     CS:BUFFER_PTR,CX
  863.                SUB     CS:CURRENT_PAGE,CX
  864.                MOV     SI,CX
  865.                XOR     DI,DI
  866.                MOV     AX,DS
  867.                MOV     ES,AX
  868.                SHR     CX,1
  869.                REP     MOVSW
  870.                MOV     SI,DI
  871.                PUSH    CS
  872.                POP     DS
  873.                CALL    READ
  874.  
  875.                POP     ES
  876.                POP     DS
  877.                POP     BP
  878.                POP     DI
  879.                POP     DX
  880.                POP     CX
  881.                POP     BX
  882.                POP     AX
  883. FORWARD_END:   RET
  884.  
  885. ;----------------------------------------------;
  886.  
  887. BACKWARD:      PUSH    DS
  888.                PUSH    ES
  889.                MOV     CX,FILEBUFF_SIZE * KILOBYTES / 2
  890.                ADD     CURRENT_PAGE,CX
  891.                MOV     DI,CX
  892.                XOR     SI,SI
  893.                MOV     AX,FILEBUFF_SEG
  894.                MOV     DS,AX
  895.                MOV     ES,AX
  896.                SHR     CX,1
  897.                REP     MOVSW
  898.                POP     ES
  899.                POP     DS
  900.  
  901.                MOV     AX,BYTES_READ
  902.                ADD     AX,FILEBUFF_SIZE * KILOBYTES
  903.                SUB     FILE_POINTER[0],AX
  904.                SBB     FILE_POINTER[2],0
  905.                XOR     SI,SI
  906.                CALL    READ
  907.                JC      BACKWARD_END
  908.                ADD     FILE_POINTER[0],FILEBUFF_SIZE * KILOBYTES / 2
  909.                ADC     FILE_POINTER[2],0
  910.  
  911. BACKWARD_END:  RET
  912.  
  913. ;----------------------------------------------;
  914. WP_FILE_PREFACE STRUC
  915. WPCorp_FILE_ID DB      -1,"WPC"                ;Signature
  916. START_OF_DOC   DW      ?,?
  917. PRODUCT_TYPE   DB      1                       ;WordPerfect
  918. WP_FILE_TYPE   DB      10                      ;Document
  919. MAJOR_VER      DB      0
  920. MINOR_VER      DB      0
  921. ENCRYPTION_KEY DW      0                       ;0 = not encrypted
  922. WP_RESERVED    DW      0
  923. WP_FILE_PREFACE ENDS
  924.  
  925. WP_PREFACE     WP_FILE_PREFACE <>
  926.  
  927. ;--------------;
  928. WORD_FILE_INFORMATION_BLOCK   STRUC
  929. wIdent         DW      0BE31H                  ;Signature
  930. dtyDW          DW      0                       ;Document type
  931. wTool          DW      0AB00H                  ;Signature
  932. pnNextFib      DW      ?                       ;Pointer to incremental save
  933. pnChar         DW      ?                       ;Pointer to Char formatting
  934. pnPlcpcd       DW      ?                       ;Pointer to piece table
  935. wReserved2     DW      ?                       ;Paragraph height table
  936. fcMac          DW      ?,?                     ;File char pos of file end
  937. pnPara         DW      ?                       ;Location of para formatting
  938. pnFntb         DW      ?                       ;Location of footnote table
  939. pnBkmk         DW      ?                       ;Bookmarks and sequence info
  940. pnSetb         DW      ?                       ;Section table
  941. pnBftb         DW      ?                       ;Buffer table
  942. pnSumd         DW      ?                       ;Summary information
  943. szSsht         DB      66 DUP(?)               ;Style sheet path
  944. wReserve       DW      ?                       ;For Windows Write use
  945. rgchPrtNm      DB      8  DUP(?)               ;Printer name
  946. pnMac          DW      ?                       ;One past end of document
  947. DOP            DB      8  DUP(?)               ;Document properties
  948. version        DB      ?                       ;word version
  949. fAsv           DB      ?                       ;Autosave
  950. pnPagb         DW      ?                       ;Word 5.0 page table
  951. pnMacBkmk      DW      ?                       ;Mac of Bkmk stuff
  952. pnFilename     DW      ?                       ;Only used for Asv files
  953. pnRhtb         DW      ?                       ;Running head table
  954. codepage       DW      ?                       ;codepage
  955. WORD_FILE_INFORMATION_BLOCK   ENDS
  956.  
  957. WORD_FIB       WORD_FILE_INFORMATION_BLOCK <>
  958.  
  959. ;--------------;
  960. QandA_HDR      STRUC
  961. sig            DB      "TBWP",0                ;Touchbase signature
  962. QandA_date     DB      13 DUP (?)              ;Date file last updated
  963. QandA_time     DB       9 DUP (?)              ;Time file last updated
  964. reltxtloc      DW      ?,?                     ;File rel loc of start of text
  965. txtsize        DW      ?,?                     ;Size of the text
  966. ver            DW      ?                       ;Version number
  967. ehdr           DB      ?                       ;End of file header
  968. QandA_HDR      ENDS
  969.  
  970. ;Q&A files have for the signature either
  971. ;    TBWP (TouchBase Word Processing file) or
  972. ;    TBTX (TouchBase TeXt file).
  973.  
  974. sig2           DB      "TBTX",0
  975.  
  976. QandA_HEADER   QandA_HDR <>
  977.  
  978. ;----------------------------------------------;
  979. GET_TYPE:      PUSH    DS
  980.                MOV     FILE_POINTER[0],0
  981.                MOV     FILE_POINTER[2],0
  982.  
  983. ;----------------;
  984. ; Executable
  985.                MOV     FILE_TYPE,OFFSET EXECUTABLE
  986.                MOV     FILE_LINE,OFFSET DUMMY_RET
  987.                MOV     BX,BAR_ADDR
  988.                ADD     BX,10                   ;Extension.
  989.                MOV     SI,BX
  990.                MOV     DS,FILENAME_SEG
  991.                MOV     DI,OFFSET EXEC_EXTENSION
  992.                MOV     CX,3
  993.                REPZ    CMPSB
  994.                JZ      EXEC_TYPE
  995.                MOV     SI,BX
  996.                MOV     DI,OFFSET EXEC_EXTENSION + 3
  997.                MOV     CX,3
  998.                REPZ    CMPSB
  999.                JNZ     GET_TYPE2
  1000. EXEC_TYPE:     POP     DS
  1001.                JMP     TYPE_END
  1002.  
  1003. ;----------------;
  1004. ;WordPerfect
  1005.  
  1006. GET_TYPE2:     MOV     DS,CS:FILEBUFF_SEG
  1007.                MOV     CS:FILE_TYPE,OFFSET DOCUMENT
  1008.                MOV     CS:FILE_LINE,OFFSET WP_LINES
  1009.                CMP     CS:BYTES_READ,SIZE WP_PREFACE
  1010.                JB      GET_TYPE3
  1011.                XOR     SI,SI
  1012.                MOV     DI,OFFSET WP_PREFACE
  1013.                MOV     CX,4
  1014.                REPZ    CMPSB
  1015.                JNZ     GET_TYPE3
  1016.                LODSW                           ;Start low word
  1017.                MOV     CS:FILE_POINTER[0],AX
  1018.                LODSW                           ;Start high word
  1019.                MOV     CS:FILE_POINTER[2],AX
  1020.                ADD     DI,4
  1021.                MOV     CX,SIZE PRODUCT_TYPE + SIZE WP_FILE_TYPE
  1022.                REPZ    CMPSB
  1023.                JNZ     GET_TYPE3
  1024.                INC     SI
  1025.                INC     SI
  1026.                INC     DI
  1027.                INC     DI
  1028.                CMPSB                           ;Encryption Key.
  1029.                JNZ     GET_TYPE3
  1030.  
  1031.                POP     DS
  1032.                MOV     DX,OFFSET ASCIIZ_NAME
  1033.                MOV     AH,4EH
  1034.                INT     21H
  1035.                MOV     AX,WORD PTR DTA.SIZE_LOW
  1036.                MOV     FILE_END[0],AX
  1037.                MOV     AX,WORD PTR DTA.SIZE_HIGH
  1038.                MOV     FILE_END[2],AX
  1039.                JMP     READ_FILE
  1040.  
  1041. ;----------------;
  1042. ;Word
  1043.  
  1044. GET_TYPE3:     MOV     CS:FILE_TYPE,OFFSET DOCUMENT
  1045.                MOV     CS:FILE_LINE,OFFSET ASCII_LINES
  1046.                MOV     CS:WORDSTAR,0FFH
  1047.                CMP     CS:BYTES_READ,SIZE WORD_FIB
  1048.                JB      GET_TYPE4
  1049.                XOR     SI,SI
  1050.                MOV     DI,OFFSET WORD_FIB
  1051.                MOV     CX,6
  1052.                REPZ    CMPSB
  1053.                JNZ     GET_TYPE4
  1054.  ;              CMP     DS:fAsv,0              ;Only if temp file.
  1055. ;               JNZ     GET_TYPE4
  1056.                MOV     AX,DS:fcMac[0]
  1057.                MOV     DX,DS:fcMac[2]
  1058.  
  1059.                POP     DS
  1060.                MOV     FILE_END[0],AX
  1061.                MOV     FILE_END[2],DX
  1062.                MOV     FILE_POINTER[0],128
  1063.                MOV     FILE_POINTER[2],0
  1064.                JMP     SHORT READ_FILE
  1065.  
  1066. ;----------------;
  1067. GET_TYPE4:     MOV     CS:FILE_TYPE,OFFSET DOCUMENT
  1068.                MOV     CS:FILE_LINE,OFFSET QandA_LINES
  1069.                CMP     CS:BYTES_READ,SIZE QandA_HEADER
  1070.                JB      GET_TYPE5
  1071.                XOR     SI,SI
  1072.                MOV     DI,OFFSET QandA_HEADER
  1073.                MOV     CX,5
  1074.                REPZ    CMPSB
  1075.                JZ      GOT_QandA
  1076.                XOR     SI,SI
  1077.                MOV     DI,OFFSET sig2
  1078.                MOV     CX,5
  1079.                REPZ    CMPSB
  1080.                JNZ     GET_TYPE5
  1081.  
  1082. GOT_QandA:     MOV     AX,DS:reltxtloc[0]
  1083.                MOV     DX,DS:reltxtloc[2]
  1084.                MOV     CX,DS:txtsize[0]
  1085.                MOV     BX,DS:txtsize[2]
  1086.                POP     DS
  1087.                MOV     FILE_POINTER[0],AX
  1088.                MOV     FILE_POINTER[2],DX
  1089.                ADD     AX,CX
  1090.                ADC     DX,BX
  1091.                MOV     FILE_END[0],AX
  1092.                MOV     FILE_END[2],DX
  1093.                JMP     SHORT READ_FILE
  1094.  
  1095. ;----------------;
  1096. ; Insert other types here
  1097.  
  1098. GET_TYPE5:
  1099.  
  1100. ;----------------;
  1101. ; ASCII if not any other special type.
  1102.  
  1103.                POP     DS
  1104.                MOV     FILE_TYPE,OFFSET DOCUMENT
  1105.                MOV     FILE_LINE,OFFSET ASCII_LINES
  1106.                MOV     AL,WORDSTAR_MASK
  1107.                MOV     WORDSTAR,AL
  1108.  
  1109.                MOV     DX,OFFSET ASCIIZ_NAME
  1110.                MOV     AH,4EH
  1111.                INT     21H
  1112.                MOV     AX,WORD PTR DTA.SIZE_LOW
  1113.                MOV     FILE_END[0],AX
  1114.                MOV     AX,WORD PTR DTA.SIZE_HIGH
  1115.                MOV     FILE_END[2],AX
  1116.  
  1117. READ_FILE:     MOV     SI,FILEBUFF_SIZE * KILOBYTES / 2
  1118.                CALL    READ
  1119.                JNC     TYPE_END
  1120.                MOV     FILE_CURRENT,FALSE
  1121.  
  1122. TYPE_END:      RET
  1123.  
  1124. ;----------------------------------------------;
  1125. CLEAR_FILE:    PUSH    ES
  1126.                MOV     BP,LISTING_LEN
  1127.                MOV     DX,STATUS_REG           ;Retrieve status register.
  1128.                MOV     ES,VIDEO_SEG
  1129.                MOV     DI,FCOLUMN_START
  1130.                MOV     BP,LISTING_LEN
  1131.                MOV     BH,COLOR.W
  1132.                MOV     AL,SPACE
  1133.  
  1134. NEXT_CLEAR:    PUSH    DI
  1135.                MOV     CX,FCOLUMN_LEN
  1136. NEXT_CLEAR2:   CALL    WRITE_CHAR
  1137.                LOOP    NEXT_CLEAR2
  1138.                POP     DI
  1139.                ADD     DI,CRT_WIDTH
  1140.                DEC     BP
  1141.                JNZ     NEXT_CLEAR
  1142.                POP     ES
  1143.                RET
  1144.  
  1145. ;--------------------------------------------------------------;
  1146. ; INPUT: BP -> Source filename; OUTPUT: ASCIIZ_NAME = filename ;
  1147. ;--------------------------------------------------------------;
  1148. MAKE_FILENAME: PUSH    DS
  1149.                MOV     DS,FILENAME_SEG         ;DS:SI -> Source name.
  1150.                MOV     SI,BP
  1151.                MOV     DI,OFFSET MARK_NAME     ;Name storage.
  1152.                MOVSB                           ;Copy mark.
  1153.                MOV     CX,8                    ;8 characters of name.
  1154. NEXT_NAME:     LODSB
  1155.                CMP     AL,SPACE                ;End of name?
  1156.                JZ      EXTENSION2              ;If yes, do extension.
  1157.                STOSB
  1158.                LOOP    NEXT_NAME
  1159. EXTENSION2:    MOV     SI,BP                   ;Retrieve name start.
  1160.                ADD     SI,10                   ;Move to extension field.
  1161.                CMP     BYTE PTR [SI],SPACE     ;Is there any extension?
  1162.                JZ      NAME_DONE               ;If no, done.
  1163.                MOV     AL,"."                  ;Else, add delimiting dot.
  1164.                STOSB
  1165.                MOV     CX,3                    ;3 characters for extension.
  1166. NEXT_EXT:      LODSB
  1167.                CMP     AL,SPACE
  1168.                JZ      NAME_DONE
  1169.                STOSB
  1170.                LOOP    NEXT_EXT
  1171. NAME_DONE:     XOR     AL,AL                   ;ASCIIZ.
  1172.                STOSB
  1173.                POP     DS
  1174.                RET
  1175.  
  1176. ;----------------------------------------------;
  1177. REMOVE_CNT     DW      ?
  1178.  
  1179. REMOVE1_MSG    DB      " marked files",0
  1180. REMOVE2_MSG    DB      " to be deleted?",0
  1181. REMOVE3_MSG    DB      " Do you wish to delete?  Y/N",0
  1182.  
  1183. REMOVE_MARKS:  PUSH    DS
  1184.                MOV     DS,FILENAME_SEG
  1185.                XOR     SI,SI
  1186.                XOR     CX,CX
  1187.                JMP     SHORT NEXT_COUNT2
  1188.  
  1189. NEXT_COUNT:    ADD     SI,SIZE FILE_RECORD
  1190. NEXT_COUNT2:   CMP     SI,LAST_ADDR
  1191.                JA      GOT_COUNT
  1192.                CMP     BYTE PTR [SI],RIGHT_ARROW
  1193.                JNZ     NEXT_COUNT
  1194.                INC     CX
  1195.                JMP     NEXT_COUNT
  1196.  
  1197. GOT_COUNT:     POP     DS
  1198.                JCXZ    MARKS_ERR
  1199.                MOV     REMOVE_CNT,CX
  1200.                MOV     SI,OFFSET REMOVE1_MSG
  1201.                CALL    REMOVE_QUERY
  1202.                JC      MARKS_END
  1203.  
  1204.                MOV     BAR_ADDR,0
  1205.                MOV     LISTING_ADDR,0
  1206.                JMP     SHORT NEXT_REMOVE3
  1207.  
  1208. NEXT_REMOVE:   CALL    GET_PARAMS
  1209.                CALL    LDOWN
  1210. NEXT_REMOVE2:  CALL    DISP_LISTING
  1211. NEXT_REMOVE3:  PUSH    DS
  1212.                MOV     DS,FILENAME_SEG
  1213.                MOV     SI,CS:BAR_ADDR
  1214.                CMP     BYTE PTR [SI],RIGHT_ARROW
  1215.                POP     DS
  1216.                JNZ     NEXT_REMOVE
  1217.                CALL    REMOVE_IT
  1218.                JC      MARKS_ERR
  1219.                CALL    CK_KEY
  1220.                JNZ     MARKS_END
  1221.                DEC     REMOVE_CNT
  1222.                JNZ     NEXT_REMOVE2
  1223.                JMP     SHORT MARKS_END
  1224.  
  1225. MARKS_ERR:     CALL    BEEP
  1226. MARKS_END:     CALL    HIDE_CURSOR
  1227.                CALL    DISPLAY_MENU
  1228.                CALL    DISP_FILE
  1229.                CALL    CLEAR_KEY
  1230.                RET
  1231.  
  1232. ;--------------;
  1233.  
  1234. REMOVE:        PUSH    DS
  1235.                MOV     SI,BAR_ADDR
  1236.                MOV     DS,FILENAME_SEG
  1237.                LODSW
  1238.                POP     DS
  1239.                CMP     AL,-1
  1240.                JZ      REMOVE_ERR
  1241.                CMP     AL,"<"
  1242.                JNZ     REMOVE2
  1243.                CMP     AH,"."
  1244.                JZ      REMOVE_ERR
  1245.  
  1246. REMOVE2:       MOV     BP,BAR_ADDR
  1247.                CALL    MAKE_FILENAME
  1248.                MOV     SI,OFFSET ASCIIZ_NAME
  1249.                CALL    REMOVE_QUERY
  1250.                JC      REMOVE_END
  1251.                CALL    REMOVE_IT
  1252.                JC      REMOVE_ERR
  1253.  
  1254.                MOV     FILE_CURRENT,FALSE
  1255.                CALL    DISP_LISTING
  1256.                CALL    DISP_FILE
  1257.                JMP     SHORT REMOVE_END
  1258.  
  1259. REMOVE_ERR:    CALL    BEEP
  1260. REMOVE_END:    CALL    HIDE_CURSOR
  1261.                CALL    DISPLAY_MENU
  1262.                RET
  1263.  
  1264. ;--------------;
  1265. ; INPUT: SI -> msg; REMOVE_CNT = count.
  1266. ; OUTPUT: CF = 1 if abort.
  1267.  
  1268. REMOVE_QUERY:  CALL    CLEAR_MENU
  1269.                CALL    MENU_OFFSET
  1270.                PUSH    ES
  1271.                PUSH    DI
  1272.                MOV     DX,STATUS_REG
  1273.                MOV     ES,VIDEO_SEG
  1274.                MOV     AL,SPACE
  1275.                CALL    WRITE_CHAR
  1276.  
  1277.                PUSH    SI
  1278.                CMP     SI,OFFSET REMOVE1_MSG
  1279.                JNZ     DO_MSG
  1280.                MOV     AX,REMOVE_CNT
  1281.                XOR     DX,DX
  1282.                CALL    DISP_STATS
  1283.  
  1284. DO_MSG:        POP     SI
  1285.                CALL    WRITE_LINE
  1286.                MOV     SI,OFFSET REMOVE2_MSG
  1287.                CALL    WRITE_LINE
  1288.                POP     DI
  1289.                ADD     DI,CRT_WIDTH
  1290.                MOV     SI,OFFSET REMOVE3_MSG
  1291.                CALL    WRITE_LINE
  1292.                POP     ES
  1293.  
  1294.                XOR     AH,AH
  1295.                INT     16H
  1296.                CMP     AH,Y_SCAN
  1297.                STC
  1298.                JNZ     QUERY_END
  1299.                CLC
  1300. QUERY_END:     RET
  1301.  
  1302. ;----------------------------------------------;
  1303. ; INPUT: DX:AX = number; DI -> Display
  1304.  
  1305. DISP_STATS:    MOV     BP,DX
  1306.                MOV     SI,AX
  1307.                XOR     CX,CX
  1308.                MOV     BX,10
  1309.                JMP     SHORT DO_DIV
  1310.  
  1311. NEXT_DIV:      CMP     CH,3
  1312.                JNZ     DO_DIV
  1313.                MOV     AL,","
  1314.                PUSH    AX
  1315.                XOR     CH,CH
  1316.                INC     CL
  1317.  
  1318. DO_DIV:        MOV     AX,BP
  1319.                XOR     DX,DX
  1320.                DIV     BX
  1321.                MOV     BP,AX
  1322.                MOV     AX,SI
  1323.                DIV     BX
  1324.                MOV     SI,AX
  1325.                MOV     AX,DX
  1326.                ADD     AL,"0"
  1327.                PUSH    AX
  1328.                ADD     CX,0101H
  1329.                OR      BP,BP
  1330.                JNZ     NEXT_DIV
  1331.                OR      SI,SI
  1332.                JNZ     NEXT_DIV
  1333.  
  1334.                XOR     CH,CH
  1335.     ;           SUB     DI,CX   ; Add this to right justify
  1336.      ;          SUB     DI,CX
  1337.                MOV     BH,COLOR.B
  1338.                MOV     DX,STATUS_REG
  1339. NEXT_WRITE:    POP     AX
  1340.                CALL    WRITE_CHAR
  1341.                LOOP    NEXT_WRITE
  1342.                RET
  1343.  
  1344. ;--------------;
  1345.  
  1346. REMOVE_IT:     MOV     BP,BAR_ADDR
  1347.                CALL    MAKE_FILENAME
  1348.                MOV     DX,OFFSET ASCIIZ_NAME
  1349.                XOR     CX,CX
  1350.                MOV     AX,4301H                ;Normal attribute.
  1351.                INT     21H
  1352.  
  1353.                PUSH    DS
  1354.                MOV     DS,FILENAME_SEG
  1355.                MOV     AL,DS:[BP]
  1356.                POP     DS
  1357.                CMP     AL,"<"
  1358.                MOV     AH,3AH                  ;RMDIR
  1359.                JZ      REMOVE_IT2
  1360.  
  1361.                MOV     AH,41H
  1362. REMOVE_IT2:    INT     21H
  1363.                JC      REMOVE_IT_END
  1364.                CMP     FAIL_FLAG,TRUE
  1365.                STC
  1366.                JZ      REMOVE_IT_END
  1367.                CALL    MOVE_RECS
  1368.                CLC
  1369. REMOVE_IT_END: RET
  1370.  
  1371. ;--------------;
  1372.  
  1373. MOVE_RECS:     PUSH    DS
  1374.                PUSH    ES
  1375.                MOV     DI,BAR_ADDR
  1376.                MOV     SI,DI
  1377.                ADD     SI,SIZE FILE_RECORD
  1378.                MOV     AX,FILENAME_SEG
  1379.                MOV     DS,AX
  1380.                MOV     ES,AX
  1381. NEXT_MOVE:     MOV     CX,SIZE FILE_RECORD / 2
  1382.                REP     MOVSW
  1383.                CMP     DI,CS:LAST_ADDR
  1384.                JNA     NEXT_MOVE
  1385.                POP     ES
  1386.                POP     DS
  1387.  
  1388.                MOV     CX,SIZE FILE_RECORD
  1389.                SUB     LAST_ADDR,CX
  1390.  
  1391.                MOV     AX,LAST_ADDR
  1392.                CMP     BAR_ADDR,AX
  1393.                JNA     MOVE_END
  1394.                SUB     BAR_ADDR,CX
  1395. MOVE_END:      RET
  1396.  
  1397. ;----------------------------------------------;
  1398. NEW_FILE:      CALL    CLEAR_MENU
  1399.                CALL    GET_NAME
  1400.                JC      NEW_END
  1401.                MOV     FILENAME,81H
  1402.                CALL    NEW_FILESPEC
  1403.                JC      NO_NEW
  1404.                MOV     FILE_CURRENT,FALSE
  1405.                MOV     BAR_ADDR,0
  1406.                MOV     LISTING_ADDR,0
  1407.                MOV     DIR_LEVEL,0
  1408.                CALL    DISP_DIR
  1409.                CALL    DISP_LISTING
  1410.                CALL    DISP_FILE
  1411.                JMP     SHORT NEW_END
  1412.  
  1413. NO_NEW:        CALL    BEEP
  1414.  
  1415. NEW_END:       CALL    HIDE_CURSOR
  1416.                CALL    DISPLAY_MENU
  1417.                RET
  1418.  
  1419. ;----------------------------------------------;
  1420. LAST_STATE     DW      ?
  1421. LAST_ZOOM      DB      SHORT_NAME
  1422.  
  1423. ZOOM:          MOV     AH,1
  1424.                JMP     SHORT DO_ZOOM
  1425. SHIFT_ZOOM:    MOV     AH,-1
  1426.  
  1427. DO_ZOOM:       MOV     AL,ZOOM_STATE
  1428.                MOV     BL,AL
  1429.                ADD     AL,AH
  1430.                JNL     CK_UPPER
  1431.                MOV     AL,FULL_FILE
  1432. CK_UPPER:      CMP     AL,FULL_FILE
  1433.                JBE     GOT_ZOOM
  1434.                MOV     AL,SHORT_NAME
  1435. GOT_ZOOM:      CALL    CHANGE_ZOOM
  1436.                RET
  1437.  
  1438. ;--------------;
  1439.  
  1440. CHANGE_ZOOM:   MOV     ZOOM_STATE,AL
  1441.                MOV     LAST_ZOOM,BL
  1442.                CMP     AL,FULL_FILE
  1443.                JNZ     DISP_ZOOM
  1444.                MOV     BX,STATE
  1445.                MOV     LAST_STATE,BX
  1446.                MOV     STATE,OFFSET FILE
  1447.  
  1448. DISP_ZOOM:     CMP     BL,FULL_FILE
  1449.                JNZ     DISP_ZOOM2
  1450.                MOV     BX,LAST_STATE
  1451.                MOV     STATE,BX
  1452.  
  1453. DISP_ZOOM2:    CALL    INIT_ZOOM
  1454.                CALL    DISP_LISTING
  1455.                CALL    DISP_FILE
  1456.                RET
  1457.  
  1458. ;----------------------------------------------;
  1459. SORT_DIR:      XOR     SORT_ORDER,DESCEND
  1460.                CALL    SORT
  1461.                CALL    DISPLAY_MENU
  1462.                MOV     FILE_CURRENT,FALSE
  1463.                CALL    DISP_LISTING
  1464.                CALL    DISP_FILE
  1465.                RET
  1466.  
  1467. ;----------------------------------------------;
  1468. DISP_LISTING:  PUSH    DS
  1469.                PUSH    ES
  1470.                MOV     DI,LCOLUMN_START
  1471.  
  1472.                MOV     SI,LISTING_ADDR
  1473.                MOV     BP,LISTING_LEN
  1474.  
  1475.                MOV     DX,STATUS_REG           ;Retrieve status register.
  1476.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  1477.                MOV     DS,FILENAME_SEG
  1478.  
  1479. NEXT_LISTING:  PUSH    DI
  1480.                MOV     CX,CS:LCOLUMN_LEN
  1481.                JCXZ    CK_LAST_LINE
  1482.  
  1483. DISPLAY_LINE:  MOV     BH,CS:COLOR.I
  1484.                CMP     BYTE PTR [SI],-1
  1485.                JZ      PAD_LISTING
  1486.                CMP     SI,CS:BAR_ADDR
  1487.                JZ      CK_BAR_COLOR
  1488.                CMP     CS:STATE,OFFSET FILE
  1489.                JNZ     DISPLAY_LINE2
  1490.                MOV     BH,CS:COLOR.W
  1491.                JMP     SHORT DISPLAY_LINE2
  1492.  
  1493. CK_BAR_COLOR:  MOV     BH,CS:COLOR.C
  1494.                CMP     CS:STATE,OFFSET FILE
  1495.                JNZ     DISPLAY_LINE2
  1496.                MOV     BH,CS:COLOR.A
  1497.  
  1498. DISPLAY_LINE2: LODSB
  1499.                CALL    WRITE_CHAR
  1500.                LOOP    DISPLAY_LINE2
  1501.  
  1502.                ADD     SI,CS:LCOLUMN_BAL
  1503.  
  1504. CK_LAST_LINE:  POP     DI
  1505.                ADD     DI,CS:CRT_WIDTH
  1506.                DEC     BP
  1507.                JNZ     NEXT_LISTING
  1508.                POP     ES
  1509.                POP     DS
  1510.                RET
  1511.  
  1512. PAD_LISTING:   CALL    PAD_LINE
  1513.                JMP     SHORT CK_LAST_LINE
  1514.  
  1515. PAD_LINE:      MOV     AL,SPACE
  1516. PAD_LINE2:     CALL    WRITE_CHAR
  1517.                LOOP    PAD_LINE2
  1518.                RET
  1519.  
  1520. ;----------------------------------------------;
  1521. DISPLAY_FLAG   DB      TRUE
  1522. LINE_CNT       DW      ?                       ;Counter for display line.
  1523. LINE_MAX       EQU     80                      ;Maximum line length supported.
  1524. ROW_CNT        DW      ?
  1525.  
  1526. DISP_FILE:     PUSH    ES
  1527.                CMP     FILE_CURRENT,TRUE
  1528.                JZ      DISP_FILE2
  1529.                CALL    OPEN_FILE
  1530.                JC      DISP_FILE_END
  1531.  
  1532. DISP_FILE2:    MOV     BH,COLOR.I
  1533.                CMP     STATE,OFFSET FILE
  1534.                JZ      DISP_FILE3
  1535.                MOV     BH,COLOR.W
  1536.  
  1537. DISP_FILE3:    MOV     DX,STATUS_REG           ;Retrieve status register.
  1538.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  1539.                MOV     DI,FCOLUMN_START
  1540.                MOV     AX,LISTING_LEN
  1541.                MOV     LINE_CNT,AX
  1542.                CALL    [FILE_TYPE]
  1543.  
  1544. DISP_FILE_END: POP     ES
  1545.                RET
  1546.  
  1547. ;----------------------;
  1548. SUBDIRECTORY   DB      " is a Subdirectory"
  1549. SUBEND         DB      0
  1550. PRESS_ENTER    DB      " Press Enter to load its files.",0
  1551.  
  1552. ; INPUT: BH=COLOR; DI=FCOLUMN_START; SI=BUFFER_PTR; DX=STATUS_REG; ES=VIDEO_SEG
  1553.  
  1554. SUBDIR:        MOV     BP,LISTING_LEN
  1555.                CALL    BLANK_LINE
  1556.                PUSH    DI
  1557.                CALL    DISPLAY_NAME
  1558.  
  1559.                MOV     SI,OFFSET SUBEND
  1560.                CMP     BYTE PTR ASCIIZ_NAME,"."
  1561.                JZ      SUBDIR2
  1562.                MOV     SI,OFFSET SUBDIRECTORY
  1563. SUBDIR2:       CALL    WRITE_LINE
  1564.  
  1565.                MOV     AL,SPACE
  1566.                CALL    REPEAT_CHAR
  1567.                POP     DI
  1568.                ADD     DI,CRT_WIDTH
  1569.  
  1570.                PUSH    DI
  1571.                MOV     CX,FCOLUMN_LEN
  1572.                CALL    WRITE_LINE
  1573.                MOV     AL,SPACE
  1574.                CALL    REPEAT_CHAR
  1575.                POP     DI
  1576.                ADD     DI,CRT_WIDTH
  1577.                DEC     BP
  1578.                DEC     BP
  1579.                DEC     BP
  1580.  
  1581. NEXT_DIR:      CALL    BLANK_LINE
  1582.                DEC     BP
  1583.                JNZ     NEXT_DIR
  1584.                RET
  1585.  
  1586. ;--------------;
  1587. BLANK_LINE:    PUSH    DI
  1588.                MOV     CX,FCOLUMN_LEN
  1589.                CALL    PAD_LINE
  1590.                POP     DI
  1591.                ADD     DI,CRT_WIDTH
  1592.                RET
  1593.  
  1594. ;--------------;
  1595. DISPLAY_NAME:  MOV     CX,FCOLUMN_LEN
  1596.                MOV     AL,SPACE
  1597.                CALL    WRITE_CHAR
  1598.                DEC     CX
  1599.                MOV     SI,OFFSET ASCIIZ_NAME
  1600.                CMP     BYTE PTR [SI],"."
  1601.                JNZ     DISPLAY_NAME2
  1602.                MOV     SI,OFFSET PARENT
  1603. DISPLAY_NAME2: CALL    WRITE_LINE
  1604.                RET
  1605.  
  1606. ;-----------;
  1607. ; Keeps track of a variable length field in CX while writing string.
  1608. WRITE_LINE:    LODSB
  1609.                OR      AL,AL
  1610.                JZ      WRITE_LINE_END
  1611.                CALL    WRITE_CHAR
  1612.                LOOP    WRITE_LINE
  1613. WRITE_LINE_END:RET
  1614.  
  1615. ;--------------;
  1616. DUMMY_RET:     RET
  1617.  
  1618. ;----------------------------------------------;
  1619. EXECUTE        DB      " is an executable file.",0
  1620.  
  1621. EXECUTABLE:    MOV     BP,LISTING_LEN
  1622.                CALL    BLANK_LINE
  1623.                PUSH    DI
  1624.                CALL    DISPLAY_NAME
  1625.  
  1626.                MOV     SI,OFFSET EXECUTE
  1627.                CALL    WRITE_LINE
  1628.  
  1629.                MOV     AL,SPACE
  1630.                CALL    REPEAT_CHAR
  1631.                POP     DI
  1632.                ADD     DI,CRT_WIDTH
  1633.  
  1634.                DEC     BP
  1635.                DEC     BP
  1636.  
  1637. NEXT_EXEC:     CALL    BLANK_LINE
  1638.                DEC     BP
  1639.                JNZ     NEXT_EXEC
  1640.                RET
  1641.  
  1642. ;----------------------------------------------;
  1643. DOCUMENT:      PUSH    DS
  1644.                MOV     SI,CURRENT_PAGE
  1645.                MOV     DISPLAY_FLAG,0
  1646.                MOV     CX,ROW
  1647.                MOV     ROW_CNT,CX
  1648.                MOV     DS,FILEBUFF_SEG
  1649.                JCXZ    NEXT_DOC
  1650. DOC_ROW:       CALL    CS:[FILE_LINE]
  1651.                DEC     CS:ROW_CNT
  1652.                JNZ     DOC_ROW
  1653.  
  1654. NEXT_DOC:      PUSH    DI
  1655.                MOV     CS:DISPLAY_FLAG,TRUE
  1656.                CALL    CS:[FILE_LINE]
  1657.                POP     DI
  1658.                ADD     DI,CS:CRT_WIDTH
  1659.                DEC     CS:LINE_CNT
  1660.                JNZ     NEXT_DOC
  1661.                POP     DS
  1662.                RET
  1663.  
  1664. ;------------------;
  1665. MULTI_BYTE     DB      0
  1666.  
  1667. WP_LINES:      MOV     CX,LINE_MAX
  1668.                MOV     BP,CS:FCOLUMN_LEN
  1669.  
  1670. WP_LINES2:     CMP     SI,CS:BUFFER_END
  1671.                JNZ     WP_CHAR
  1672.                CMP     CS:EOF_FLAG,TRUE
  1673.                JZ      WP_PAD
  1674.                MOV     CS:BUFFER_PTR,SI
  1675.                CALL    FORWARD
  1676.                JC      WP_END
  1677.                MOV     SI,CS:BUFFER_PTR
  1678.  
  1679. WP_CHAR:       LODSB
  1680.                CMP     CS:MULTI_BYTE,0
  1681.                JNZ     FIND_MULTI
  1682.                CMP     AL,CR
  1683.                JZ      WP_PAD
  1684.                CMP     AL,LF
  1685.                JZ      WP_PAD
  1686.                CMP     AL,SPACE
  1687.                JB      WP_LINES2
  1688.                CMP     AL,80H
  1689.                JB      GOOD_WP
  1690.  
  1691.                CMP     AL,0C0H
  1692.                JB      WP_LINES2
  1693.                MOV     CS:MULTI_BYTE,AL
  1694.                JMP     WP_LINES2
  1695.  
  1696. GOOD_WP:       PUSH    CX
  1697.                MOV     CX,1
  1698.                CALL    CK_WP_DISP
  1699.                POP     CX
  1700.                LOOP    WP_LINES2
  1701.                CALL    CK_BUFF
  1702.                JC      WP_END
  1703.                CMP     BYTE PTR [SI],CR
  1704.                JNZ     WP_END
  1705.                CMP     BYTE PTR [SI],LF
  1706.                JNZ     WP_END
  1707.                INC     SI
  1708. WP_END:        RET
  1709.  
  1710. FIND_MULTI:    CMP     AL,CS:MULTI_BYTE
  1711.                JNZ     WP_LINES2
  1712.                MOV     CS:MULTI_BYTE,0
  1713.                JMP     WP_LINES2
  1714.  
  1715. WP_PAD:        MOV     AL,SPACE
  1716. CK_WP_DISP:    CMP     CS:DISPLAY_FLAG,TRUE
  1717.                JNZ     CK_WP_END
  1718.                MOV     BL,AL
  1719. WP_WRITE:      CALL    WRITE_CHAR
  1720.                DEC     BP
  1721.                JNZ     WP_LOOP
  1722.                MOV     CS:DISPLAY_FLAG,FALSE
  1723. WP_LOOP:       LOOP    CK_WP_DISP
  1724. CK_WP_END:     RET
  1725.  
  1726. ;--------------;
  1727. FF_CODE        DB      0
  1728.  
  1729. QandA_LINES:   MOV     CX,LINE_MAX
  1730.                MOV     BP,CS:FCOLUMN_LEN
  1731.  
  1732. QandA_LINES2:  CMP     SI,CS:BUFFER_END
  1733.                JNZ     QandA_CHAR
  1734.                CMP     CS:EOF_FLAG,TRUE
  1735.                JZ      QandA_PAD
  1736.                MOV     CS:BUFFER_PTR,SI
  1737.                CALL    FORWARD
  1738.                JC      QandA_END
  1739.                MOV     SI,CS:BUFFER_PTR
  1740.  
  1741. QandA_CHAR:    LODSB
  1742.                CMP     CS:FF_CODE,0
  1743.                JNZ     FIND_FF_CODE
  1744.                CMP     AL,0FFH
  1745.                JNZ     GOOD_QandA
  1746.                MOV     CS:FF_CODE,AL
  1747.                JMP     QandA_LINES2
  1748.  
  1749. GOOD_QandA:    PUSH    CX
  1750.                MOV     CX,1
  1751.                CALL    CK_QandA_DISP
  1752.                POP     CX
  1753.                LOOP    QandA_LINES2
  1754.                CALL    CK_BUFF
  1755.                JC      QandA_END
  1756.                LODSB
  1757.                CMP     AL,0FFH
  1758.                JZ      CK_CR
  1759.                DEC     SI
  1760.                JMP     SHORT QandA_END
  1761. CK_CR:         CALL    CK_BUFF
  1762.                JC      QandA_END
  1763.                LODSB
  1764.                CMP     AL,1       ;CR
  1765.                JZ      QandA_END
  1766.                DEC     SI
  1767.                DEC     SI
  1768. QandA_END:     RET
  1769.  
  1770. FIND_FF_CODE:  MOV     AH,CS:FF_CODE
  1771.                CMP     AH,0FFH
  1772.                JZ      FIND_FF_CODE2
  1773.                DEC     CS:FF_CODE
  1774.                JMP     QandA_LINES2
  1775.  
  1776. FIND_FF_CODE2: CMP     AL,1
  1777.                JNZ     FIND_FF_CODE3
  1778.                MOV     CS:FF_CODE,0
  1779.                JMP     SHORT QandA_PAD
  1780. FIND_FF_CODE3: XOR     AL,AL
  1781.                XOR     AH,32
  1782.                CMP     AH,32
  1783.                JBE     FOUND_FF
  1784.                MOV     AL,2
  1785. FOUND_FF:      JMP     QandA_LINES2
  1786.  
  1787.  
  1788. QandA_PAD:     MOV     AL,SPACE
  1789. CK_QandA_DISP: CMP     CS:DISPLAY_FLAG,TRUE
  1790.                JNZ     CK_QandA_END
  1791.                MOV     BL,AL
  1792. QandA_WRITE:   CALL    WRITE_CHAR
  1793.                DEC     BP
  1794.                JNZ     QandA_LOOP
  1795.                MOV     CS:DISPLAY_FLAG,FALSE
  1796. QandA_LOOP:    LOOP    CK_QandA_DISP
  1797. CK_QandA_END:  RET
  1798.  
  1799. ;--------------;
  1800. ASCII_LINES:   MOV     CX,LINE_MAX
  1801.                MOV     BP,CS:FCOLUMN_LEN
  1802.  
  1803. ASCII_LINES2:  CMP     SI,CS:BUFFER_END
  1804.                JNZ     ASCII_CHAR
  1805.                CMP     CS:EOF_FLAG,TRUE
  1806.                JZ      ASCII_PAD
  1807.                MOV     CS:BUFFER_PTR,SI
  1808.                CALL    FORWARD
  1809.                JC      ASCII_END
  1810.                MOV     SI,CS:BUFFER_PTR
  1811.  
  1812. ASCII_CHAR:    LODSB
  1813.                AND     AL,CS:WORDSTAR
  1814.                CMP     AL,CR
  1815.                JZ      ASCII_PAD
  1816.                CMP     AL,TAB
  1817.                JZ      ASCII_TAB
  1818.                CMP     AL,LF
  1819.                JZ      ASCII_LINES2
  1820.                PUSH    CX
  1821.                MOV     CX,1
  1822.                CALL    CK_ASCII_DISP
  1823.                POP     CX
  1824.                LOOP    ASCII_LINES2
  1825.                CALL    CK_BUFF
  1826.                JC      ASCII_END
  1827.                CMP     BYTE PTR [SI],CR
  1828.                JNZ     ASCII_END
  1829.                INC     SI
  1830. ASCII_END:     RET
  1831.  
  1832. ASCII_TAB:     PUSH    CX
  1833.                DEC     CX
  1834.                AND     CX,7
  1835.                INC     CX
  1836.                PUSH    CX
  1837.                CALL    ASCII_PAD
  1838.                POP     AX
  1839.                POP     CX
  1840.                SUB     CX,AX
  1841.                JNZ     ASCII_LINES2
  1842.                JMP     ASCII_END
  1843.  
  1844. ASCII_PAD:     MOV     AL,SPACE
  1845. CK_ASCII_DISP: CMP     CS:DISPLAY_FLAG,TRUE
  1846.                JNZ     CK_ASCII_END
  1847.                MOV     BL,AL
  1848. ASCII_WRITE:   CALL    WRITE_CHAR
  1849.                DEC     BP
  1850.                JNZ     ASCII_LOOP
  1851.                MOV     CS:DISPLAY_FLAG,FALSE
  1852. ASCII_LOOP:    LOOP    CK_ASCII_DISP
  1853. CK_ASCII_END:  RET
  1854.  
  1855. ;--------------;
  1856. CK_BUFF:       CMP     SI,CS:BUFFER_END
  1857.                CLC
  1858.                JNZ     CK_BUFF_END
  1859.                CMP     CS:EOF_FLAG,TRUE
  1860.                STC
  1861.                JZ      CK_BUFF_END
  1862.                MOV     CS:BUFFER_PTR,SI
  1863.                CALL    FORWARD
  1864.                MOV     SI,CS:BUFFER_PTR
  1865. CK_BUFF_END:   RET
  1866.  
  1867. ;----------------------------------------------;
  1868. DIRECTORY      DB      "    Directory of ",0
  1869.  
  1870. DISP_DIR:      PUSH    ES
  1871.                MOV     SI,OFFSET WORKING_DIR
  1872.                CALL    GET_DIR
  1873.  
  1874.                MOV     DX,STATUS_REG           ;Retrieve status register.
  1875.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  1876.                MOV     BH,COLOR.B
  1877.                MOV     DI,CRT_WIDTH
  1878.                MOV     CX,DI
  1879.                SHR     CX,1
  1880.  
  1881.                MOV     SI,OFFSET DIRECTORY
  1882.                CALL    WRITE_LINE
  1883.                MOV     AL,WORKING_DRIVE
  1884.                ADD     AL,"A"
  1885.                CALL    WRITE_CHAR
  1886.                DEC     CX
  1887.                MOV     AL,":"
  1888.                CALL    WRITE_CHAR
  1889.                DEC     CX
  1890.                MOV     SI,OFFSET WORKING_DIR
  1891.                CALL    WRITE_LINE
  1892.                CALL    PAD_LINE
  1893.                POP     ES
  1894.                RET
  1895.  
  1896. ;----------------------------------------------;
  1897. ENTER:         MOV     BP,BAR_ADDR
  1898.                CALL    MAKE_FILENAME
  1899.                CMP     MARK_NAME,"<"
  1900.                JNZ     DO_ZOOM2
  1901.  
  1902.                PUSH    WORD PTR ASCIIZ_NAME
  1903.                MOV     FILENAME,OFFSET ASCIIZ_NAME
  1904.                CALL    NEW_FILESPEC
  1905.                POP     AX
  1906.  
  1907.                CMP     AL,"."                  ;Parent dir?
  1908.                JNZ     NEXT_LEVEL
  1909.                CMP     DIR_LEVEL,0
  1910.                JZ      NEXT_LEVEL
  1911.  
  1912.                DEC     DIR_LEVEL
  1913.                MOV     BX,DIR_LEVEL
  1914.                SHL     BX,1
  1915.                SHL     BX,1
  1916.                MOV     AX,DIR_POINTERS.TOP_LOC[BX]
  1917.                MOV     LISTING_ADDR,AX
  1918.                MOV     AX,DIR_POINTERS.BAR_LOC[BX]
  1919.                MOV     BAR_ADDR,AX
  1920.                CMP     AX,LAST_ADDR
  1921.                JBE     SHORT UPDATE_DISP
  1922.                MOV     DIR_LEVEL,0
  1923.                JMP     SHORT HOME_BAR
  1924.  
  1925. NEXT_LEVEL:    MOV     BX,DIR_LEVEL
  1926.                CMP     BX,DIR_LEVEL_MAX
  1927.                JZ      HOME_BAR
  1928.                SHL     BX,1
  1929.                SHL     BX,1
  1930.                MOV     AX,LISTING_ADDR
  1931.                MOV     DIR_POINTERS.TOP_LOC[BX],AX
  1932.                MOV     AX,BAR_ADDR
  1933.                MOV     DIR_POINTERS.BAR_LOC[BX],AX
  1934.                INC     DIR_LEVEL
  1935. HOME_BAR:      MOV     BAR_ADDR,0
  1936.                MOV     LISTING_ADDR,0
  1937.  
  1938. UPDATE_DISP:   CALL    DISP_DIR
  1939.                CALL    DISP_LISTING
  1940.                CALL    DISP_FILE
  1941.                JMP     SHORT LOAD_END
  1942.  
  1943. DO_ZOOM2:      MOV     AL,LAST_ZOOM
  1944.                MOV     BL,ZOOM_STATE
  1945.                CMP     BL,FULL_FILE
  1946.                JZ      DO_ZOOM3
  1947.                MOV     AL,FULL_FILE
  1948. DO_ZOOM3:      CALL    CHANGE_ZOOM
  1949.  
  1950. LOAD_END:      RET
  1951.  
  1952.  
  1953. ;------------------------------------------------------------------;
  1954. ; Parse drive and/or path delimiters.  Convert filespec to ASCIIZ. ;
  1955. ; If drive delimiter found (:), change to requested drive.         ;
  1956. ;------------------------------------------------------------------;
  1957. ; OUTPUT: CY=1 if invalid filespec.
  1958.  
  1959. NEW_FILESPEC:  MOV     SI,FILENAME
  1960. PARSE_LEADING: LODSB                           ;Get a byte.
  1961.                CMP     AL,SPACE                ;Is it a space char or below?
  1962.                JA      LEADING_END             ;If no, done here.
  1963.                CMP     AL,CR                   ;Is it carriage return?
  1964.                JNZ     PARSE_LEADING           ;If no, get next byte.
  1965. LEADING_END:   DEC     SI                      ;Adjust pointer to string start.
  1966.                MOV     BP,SI                   ;Save start of filespec.
  1967.                MOV     BX,SI                   ;Use BX as filename start pointer
  1968.  
  1969. FIND_END:      LODSB                           ;Get a byte.
  1970.                CMP     AL,":"                  ;Is it a drive delimiter?
  1971.                JNZ     CK_SLASH                ;If no, check path delimiter.
  1972.                CALL    RESTORE_DIR
  1973.                MOV     DL,[SI-2]               ;Else, retrieve drive specifier.
  1974.                AND     DL,5FH                  ;Capitalize.
  1975.                SUB     DL,"A"                  ;Convert to DOS format.
  1976.                MOV     WORKING_DRIVE,DL
  1977.                MOV     AH,0EH                  ;Change drive.
  1978.                INT     21H
  1979.                PUSH    SI
  1980.                MOV     SI,OFFSET CURRENT_DIR
  1981.                CALL    GET_DIR
  1982.                POP     SI
  1983.                MOV     BX,SI                   ;Save as filename start.
  1984.                JMP     FIND_END                ;Continue parsing.
  1985.  
  1986. CK_SLASH:      CMP     AL,"\"                  ;Is it a path delimiter?
  1987.                JNZ     CK_DELIMITER            ;If no, check switch character.
  1988.                MOV     BX,SI                   ;Else, save as filename start.
  1989. CK_DELIMITER:  CMP     AL,"/"                  ;Is it a switch delimiter?
  1990.                JZ      FOUND_END               ;If yes, end of filespec.
  1991.                CMP     AL,SPACE                ;Is it above space character?
  1992.                JA      FIND_END                ;If yes, continue until find end.
  1993.  
  1994. FOUND_END:     DEC     SI                      ;Adjust.
  1995.                MOV     FILESPEC_END,SI
  1996.                PUSH    [SI]
  1997.                MOV     BYTE PTR [SI],0         ;Convert to ASCIIZ.
  1998.  
  1999. ;-------------------------------------------------;
  2000. FIND_PATH:     CMP     BP,SI                   ;No filespec?
  2001.                JZ      GLOBAL
  2002.                CMP     BYTE PTR [SI - 1],":"   ;Drive-only filespec?
  2003.                JZ      GLOBAL
  2004.  
  2005. CK_ROOT:       MOV     CX,1                    ;CX=1:"\"not=root; CX=0:"\"=root.
  2006.                CMP     BYTE PTR [BX - 1],"\"   ;Filespec start path delimiter?
  2007.                JNZ     CK_PATH                 ;If no, not root.
  2008.                CMP     BYTE PTR [BX - 2],":"   ;Else, is it prefaced with colon?
  2009.                JZ      ROOT                    ;If yes, then root.
  2010.                CMP     BYTE PTR [BX - 2],SPACE ;Is it prefaced with white space?
  2011.                JA      CK_TRAILING             ;If no, then trailing slash?
  2012. ROOT:          DEC     CX                      ;Else, root; CX=0 for root flag.
  2013.                JMP     SHORT CK_PATH           ;Change default path.
  2014.  
  2015. CK_TRAILING:   CMP     BX,SI                   ;Filename start = filespec end?
  2016.                JNZ     CK_PATH                 ;If no, not trailing slash.
  2017.                MOV     BYTE PTR [BX - 1],0     ;Else, zero out trailing slash
  2018.                MOV     BX,OFFSET STAR_DOT_STAR ; and use global filespec.
  2019.  
  2020. CK_PATH:       MOV     DX,BP                   ;See if filespec is a path
  2021.                CALL    CHANGE_DIR              ; by changing directory.
  2022.                JC      CK_FILESPEC             ;If failed, remove filename.
  2023. GLOBAL:        MOV     BX,OFFSET STAR_DOT_STAR ;Else, use global for filename.
  2024.                JMP     SHORT GOT_FILESPEC      ;Done here.
  2025.  
  2026. CK_FILESPEC:   JCXZ    SAVE_DELIMIT            ;Is path root?; If yes leave "\".
  2027.                DEC     BX                      ;Else, point to slash.
  2028. SAVE_DELIMIT:  PUSH    [BX]                    ;Preserve filename start.
  2029.                MOV     BYTE PTR [BX],0         ;Temp ASCIIZ twixt path and name.
  2030.                CALL    CHANGE_DIR              ;Change directory.
  2031.                POP     [BX]                    ;Restore first byte of filename.
  2032.                JCXZ    GOT_FILESPEC            ;If root, done here.
  2033.                INC     BX                      ;Else, readjust filename pointer.
  2034. GOT_FILESPEC:  MOV     FILESPEC,BX             ;Save filename.
  2035.                POP     [SI]
  2036.  
  2037.                CALL    PARSE
  2038.                JC      NEW_FILE_END
  2039.                CALL    FIND_FILES
  2040. NEW_FILE_END:  RET
  2041.  
  2042. ;----------------------------------------------;
  2043. ; OUTPUT: CF=1 if no files found.
  2044.  
  2045. FIND_FILES:    PUSH    ES                      ;Preserve extra segment.
  2046.                MOV     ES,FILENAME_SEG         ;ES:DI -> filename storage.
  2047.                XOR     DI,DI
  2048.                MOV     DX,FILESPEC
  2049.  
  2050.                MOV     CX,ATTR
  2051.                MOV     AH,4EH                  ;Find first.
  2052.                MOV     SI,FILESPEC_END
  2053.                PUSH    [SI]
  2054.                MOV     BYTE PTR [SI],0
  2055.                INT     21H                     ;Any files?
  2056.                POP     [SI]
  2057.                MOV     DX,OFFSET NOT_FOUND
  2058.                JC      FILES_END               ;If no, assumed right.
  2059.  
  2060.                MOV     AX,SPACE SHL 8 + SPACE
  2061.                MOV     CX,FILENAME_SIZE / 2 * KILOBYTES
  2062.                REP     STOSW                   ;Initialize with spaces.
  2063.                XOR     DI,DI
  2064.  
  2065. FIND_NEXT:     CALL    STORE_NAME              ;Store a filename.
  2066.                CMP     DI,TEMP_RECORD - SIZE FILE_RECORD
  2067.                JA      FILES_DONE
  2068.                MOV     AH,4FH                  ;Find Next Matching.
  2069.                INT     21H
  2070.                JNC     FIND_NEXT               ;If successful store filename.
  2071.  
  2072. FILES_DONE:    MOV     AX,-1                   ;Else, mark the end with -1.
  2073.                STOSW
  2074.                SUB     DI,SIZE FILE_RECORD + 2
  2075.                JNC     STORE_LAST
  2076.                XOR     DI,DI
  2077. STORE_LAST:    MOV     LAST_ADDR,DI
  2078.                CALL    SORT                    ;Sort 'em.
  2079.                CLC
  2080. FILES_END:     POP     ES                      ;Restore extra segment.
  2081.                RET
  2082.  
  2083. ;----------------------------------------------;
  2084. READ_ONLY      EQU     01H
  2085. HIDDEN         EQU     02H
  2086. SUB_DIR        EQU     10H
  2087. NOT_MODIFIED   EQU     00H
  2088. MODIFIED       EQU     20H
  2089. IGNORE         EQU     -1
  2090. MODIFIED_TYPE  DB      IGNORE
  2091.  
  2092. PRIOR          EQU     0
  2093. AFTER          EQU     1
  2094. DATE_FLAG      DB      IGNORE
  2095. FILEDATE       DW      ?
  2096.  
  2097.  
  2098. STORE_NAME:    MOV     AL,DTA.ATTRIBUTE
  2099.                TEST    AL,READ_ONLY
  2100.                JZ      STORE_NAME2
  2101.                TEST    ATTR,READ_ONLY
  2102.                JZ      LILLY_END
  2103.  
  2104. STORE_NAME2:   TEST    AL,SUB_DIR
  2105.                JNZ     STORE_NAME4
  2106.                CMP     MODIFIED_TYPE,IGNORE
  2107.                JZ      STORE_NAME3
  2108.                AND     AL,MODIFIED
  2109.                CMP     AL,MODIFIED_TYPE
  2110.                JNZ     LILLY_END
  2111.  
  2112. STORE_NAME3:   CMP     DATE_FLAG,IGNORE
  2113.                JZ      STORE_NAME4
  2114.                MOV     AX,FILEDATE
  2115.                CMP     DATE_FLAG,PRIOR
  2116.                JZ      CK_PRIOR
  2117.                CMP     DTA.FILE_DATE,AX
  2118.                JAE     STORE_NAME4
  2119.                JMP     SHORT LILLY_END
  2120.  
  2121. CK_PRIOR:      CMP     DTA.FILE_DATE,AX
  2122.                JBE     STORE_NAME4
  2123.                JMP     SHORT LILLY_END
  2124.  
  2125. STORE_NAME4:   MOV     SI,OFFSET DTA.FILE_NAME ;Point to filename.
  2126.                INC     DI                      ;Bump past Mark.
  2127.  
  2128.                MOV     CX,SIZE LIST_NAME       ;Store 12 bytes of filename.
  2129.                CMP     BYTE PTR [SI],"."
  2130.                JNZ     NEXT_STORE
  2131.                CMP     BYTE PTR [SI+1],"."
  2132.                JZ      STORE_DOTDOT
  2133.                DEC     DI
  2134. LILLY_END:     JMP     STORE_NAME_END
  2135.  
  2136. STORE_DOTDOT:  LODSB
  2137.                STOSB
  2138.                STOSB
  2139.                ADD     DI,SIZE LIST_NAME - 2
  2140.                JMP     SHORT CK_DIR
  2141.  
  2142. EXTENSION:     ADD     DI,CX
  2143.                MOV     CX,3
  2144.                SUB     DI,CX
  2145.  
  2146. NEXT_STORE:    LODSB                           ;Get a byte.
  2147.                OR      AL,AL                   ;End of filename?
  2148.                JZ      END_STORE               ;If yes, finish with blanks.
  2149.                CMP     AL,"."                  ;Is it the period?
  2150.                JZ      EXTENSION
  2151.  
  2152.                STOSB                           ;Store byte.
  2153.                LOOP    NEXT_STORE              ;Get next byte.
  2154. END_STORE:     ADD     DI,CX
  2155.  
  2156. CK_DIR:        MOV     BX,10                   ;Convert to decimal.
  2157.                TEST    DTA.ATTRIBUTE,10H
  2158.                JZ      STORE_SIZE
  2159.                MOV     BYTE PTR ES:[DI-SIZE LIST_NAME-SIZE MARK],"<"
  2160.                MOV     BYTE PTR ES:[DI],">"
  2161.                ADD     DI,SIZE LIST_DATE
  2162.                JMP     SHORT STORE_DATE
  2163.  
  2164. STORE_SIZE:    PUSH    DI                      ;Save pointer.
  2165.                ADD     DI,SIZE LIST_BYTES      ;Move to end of bytes field.
  2166.                MOV     DX,DTA.SIZE_LOW         ;Retrieve high and low words
  2167.                MOV     AX,DTA.SIZE_HIGH        ; of size in bytes.
  2168.  
  2169.                STD                             ;Reverse direction.
  2170. NEXT_SIZE:     MOV     CX,DX                   ;Low word in CX.
  2171.                XOR     DX,DX                   ;Zero in high half.
  2172.                DIV     BX                      ;Convert to decimal.
  2173.                XCHG    AX,CX                   ;Retrieve low word.
  2174.                DIV     BX
  2175.                XCHG    AX,DX                   ;Retrieve remainder.
  2176.                ADD     AL,"0"                  ;Convert to ASCII.
  2177.                STOSB                           ;Store it.
  2178.                MOV     AX,CX                   ;Are we done?
  2179.                OR      CX,DX
  2180.                JNZ     NEXT_SIZE               ;If no, divide again.
  2181.  
  2182.                CLD                             ;Back to forward direction.
  2183.                POP     DI                      ;Retrieve pointer.
  2184.                ADD     DI,SIZE LIST_DATE       ;Move to date field.
  2185.  
  2186. STORE_DATE:    MOV     DX,DTA.FILE_DATE        ;Retrieve date.
  2187.                MOV     AX,DX
  2188.                MOV     CL,5                    ;Shift to lowest bits.
  2189.                SHR     AX,CL
  2190.                AND     AX,1111B                ;Mask off all but month.
  2191.                MOV     CL,0FFH                 ;Flag as no leading zeros.
  2192.                MOV     CH,"-"                  ;Delimiting character.
  2193.                CALL    STORE_WORD              ;Store it.
  2194.  
  2195.                MOV     AX,DX                   ;Retrieve date.
  2196.                AND     AX,11111B               ;Mask off all but day.
  2197.                XOR     CL,CL                   ;Flag include leading zeros.
  2198.                CALL    STORE_WORD              ;Store it.
  2199.  
  2200.                MOV     AX,DX                   ;Retrieve date for last time.
  2201.                MOV     CL,9
  2202.                SHR     AX,CL                   ;Mask off all but year.
  2203.                ADD     AX,80                   ;Adjust to ASCII.
  2204.                CMP     AX,100                  ;Past year 2000?
  2205.                JB      DISPLAY_DATE            ;If no, display. Else, adjust for
  2206.                SUB     AX,100                  ; next century. (Planning ahead!)
  2207. DISPLAY_DATE:  XOR     CL,CL                   ;Display leading zeros.
  2208.                MOV     CH,SPACE
  2209.                CALL    STORE_WORD              ;Store it.
  2210.  
  2211. TIME:          INC     DI                      ;Move to time field.
  2212.                MOV     DX,DTA.FILE_TIME        ;Retrieve time.
  2213.                MOV     AX,DX
  2214.                MOV     CL,11                   ;Shift to hours bits.
  2215.                SHR     AX,CL
  2216.                PUSH    AX
  2217.                CMP     AX,12                   ;Past noon?
  2218.                JBE     MERIDIAN
  2219.                SUB     AX,12                   ;If yes, adjust.
  2220. MERIDIAN:      CMP     AX,0                    ;Midnight?
  2221.                JNZ     NOT_MIDNIGHT
  2222.                MOV     AX,12                   ;If yes, adjust.
  2223. NOT_MIDNIGHT:  MOV     CL,0FFH                 ;Suppress leading zeros.
  2224.                MOV     CH,":"
  2225.                CALL    STORE_WORD              ;Store it.
  2226.  
  2227.                MOV     AX,DX                   ;Retrieve time.
  2228.                MOV     CL,5                    ;Shift to minutes bits.
  2229.                SHR     AX,CL
  2230.                AND     AX,111111B              ;Mask off all but minutes.
  2231.                XOR     CL,CL
  2232.                POP     DX                      ;Retrieve hours.
  2233.                MOV     CH,"p"                  ;Assume PM.
  2234.                CMP     DX,12                   ;Is it PM?
  2235.                JAE     PM
  2236.                MOV     CH,"a"                  ;If no, AM.
  2237.  
  2238. PM:            CALL    STORE_WORD              ;Store it.
  2239. STORE_NAME_END:RET                             ;Done here.
  2240.  
  2241. ;-----------------------------------------------------------------------;
  2242. ; Converts a two byte hex number to decimal followed by delimiter.      ;
  2243. ; INPUT: AX = hex number; BL = 10; CH = delimiter character to store.   ;
  2244. ;   CL = 0 if zeros are to be stored; CL = -1 if leading zeros ignored. ;
  2245. ;   ES:DI points to storage.                                            ;
  2246. ;-----------------------------------------------------------------------;
  2247. STORE_WORD:    DIV     BL                      ;Divide by ten.
  2248.                ADD     AX,"00"                 ;Convert to ASCII.
  2249.                CMP     CL,0                    ;Are we to display leading zero?
  2250.                JZ      STORE_IT                ;If yes, store as is.
  2251.                CMP     AL,"0"                  ;Is it a leading zero?
  2252.                JNZ     STORE_IT                ;If no, store it.
  2253.                MOV     AL,SPACE                ;Else, store a space.
  2254. STORE_IT:      STOSW
  2255.                MOV     AL,CH                   ;Store delimiter character also.
  2256.                STOSB
  2257.                RET
  2258.  
  2259. ;------------------------------------------------------------------------;
  2260. ; These four subroutines control in which column the sorting will start. ;
  2261. ;------------------------------------------------------------------------;
  2262. SORTS_CODE     DB      76H,  77H, 72H,   73H, 72H, 77H
  2263.                        ;JBE, JA,  JB     JAE, JB,  JA
  2264.  
  2265. SORT_TABLE     DW      1,12,  10,3,  14,8,  30,2
  2266.                        ;Name  Ext    Size   Date
  2267.                        ;offset,length
  2268.  
  2269. SORT_NAME:     MOV     BP,NAME_SORT
  2270.                JMP     SHORT STORE_SORT
  2271.  
  2272. SORT_EXT:      MOV     BP,EXT_SORT
  2273.                JMP     SHORT STORE_SORT
  2274.  
  2275. SORT_SIZE:     MOV     BP,SIZE_SORT
  2276.                JMP     SHORT STORE_SORT
  2277.  
  2278. SORT_DATE:     MOV     BP,DATE_SORT
  2279.  
  2280. STORE_SORT:    MOV     SORT_INDEX,BP
  2281.                CALL    SORT
  2282.                CALL    DISP_LISTING
  2283.                RET
  2284.  
  2285. ;---------------------------------------------------;
  2286. ; Insertion sort;  Doesn't destroy secondary sorts. ;
  2287. ;---------------------------------------------------;
  2288. SORT:          CMP     SORT_ORDER,NO_SORT
  2289.                JNZ     DO_SORT
  2290.                RET
  2291.  
  2292. DO_SORT:       MOV     SI,OFFSET SORTS_CODE
  2293.                ADD     SI,SORT_ORDER
  2294. MODIFY_CODE:   LODSB
  2295.                MOV     S1,AL
  2296.                LODSB
  2297.                MOV     S2,AL
  2298.                MOV     S3,AL
  2299.                MOV     S4,AL
  2300.                MOV     S6,AL
  2301.                MOV     S8,AL
  2302.                LODSB
  2303.                MOV     S5,AL
  2304.                MOV     S7,AL
  2305.  
  2306. ;----------------------------------------------;
  2307.  
  2308.                MOV     BP,SORT_INDEX           ;BP = Index in sort table field.
  2309.                MOV     BX,SORT_TABLE[BP]       ;BX = Sort field offset.
  2310.                INC     BP
  2311.                INC     BP
  2312.                MOV     BP,SORT_TABLE[BP]       ;BP = Sort field length
  2313.  
  2314.                XOR     SI,SI                   ;SI = First record.
  2315.                MOV     DI,SIZE FILE_RECORD     ;DI = Second record.
  2316.                PUSH    DS
  2317.                PUSH    ES
  2318.                MOV     ES,FILENAME_SEG
  2319.                MOV     DS,FILENAME_SEG
  2320.  
  2321.                CMP     BYTE PTR [SI],-1
  2322.                JZ      SORT_END
  2323.                CMP     BYTE PTR [DI],-1
  2324.                JZ      SORT_END
  2325.  
  2326. NEXT_SORT:     CMP     DI,CS:LAST_ADDR         ;Sort is done when last record.
  2327.                JA      SORT_END
  2328.  
  2329.                PUSH    SI                      ;Save record pointers.
  2330.                PUSH    DI
  2331.                MOV     AX,SI                   ;Carry source pointer in AX.
  2332.                MOV     DX,DI                   ;Carry destination pointer in DX.
  2333.  
  2334. NEXT_RECORD:   ADD     SI,BX                   ;Index to sort field.
  2335.                ADD     DI,BX
  2336.                MOV     CX,BP                   ;Field length.
  2337.                CMP     BP,2                    ;Sort by date is special case.
  2338.                JZ      DO_DATE
  2339. COMPARE:       REPZ    CMPSB                   ;Compare the fields.
  2340.  
  2341. S1 LABEL BYTE
  2342.                JBE     NO_SWITCH               ;If below or equal, no switch.
  2343.  
  2344. SWAP:          CMP     DX,TEMP_RECORD          ;Else, if DX points to temporary
  2345.                JZ      DO_SWAP                 ; storage, safe to move.
  2346.                MOV     SI,DX                   ;Else, move destination record
  2347.                MOV     DX,TEMP_RECORD          ; to temporary storage.
  2348.                MOV     DI,DX
  2349.                MOV     CX,SIZE FILE_RECORD / 2
  2350.                REP     MOVSW
  2351.  
  2352. DO_SWAP:       MOV     SI,AX                   ;Restore source pointer
  2353.                MOV     DI,SI                   ;Destination = source +
  2354.                ADD     DI,SIZE FILE_RECORD     ; field size.
  2355.                MOV     CX,SIZE FILE_RECORD / 2
  2356.                REP     MOVSW                   ;Move the record.
  2357.  
  2358.                MOV     DI,DX                   ;Prepare for next compare.
  2359.                SUB     AX,SIZE FILE_RECORD     ;Destination = temporary.
  2360.                MOV     SI,AX                   ;Move one record towards start.
  2361.                JNC     NEXT_RECORD
  2362.  
  2363. NO_SWITCH:     MOV     SI,TEMP_RECORD          ;If DX doesn't point to temporary
  2364.                CMP     DX,SI                   ; storage, no move was made; next
  2365.                JNZ     NEXT_INSERT             ; compare.
  2366.                MOV     DI,AX                   ;Else, move temporary record
  2367.                ADD     DI,SIZE FILE_RECORD     ; into last move location.
  2368.                MOV     CX,SIZE FILE_RECORD / 2
  2369.                REP     MOVSW
  2370.  
  2371. NEXT_INSERT:   POP     DI                      ;Restore outside loop pointers.
  2372.                POP     SI
  2373.                ADD     SI,SIZE FILE_RECORD     ;Move both source and destination
  2374.                ADD     DI,SIZE FILE_RECORD     ; to the next record.
  2375.                JMP     NEXT_SORT
  2376.  
  2377. SORT_END:      POP     ES
  2378.                POP     DS
  2379.                MOV     FILE_CURRENT,FALSE
  2380.                RET
  2381.  
  2382. ;------------------;
  2383.  
  2384. DO_DATE:       REPZ    CMPSB                   ;Compare year first.
  2385.  
  2386. S2 LABEL BYTE
  2387.                JA      SWAP                    ;If above, swap.
  2388.                JNZ     NO_SWITCH
  2389.                SUB     SI,8                    ;Else, adjust and do month/day.
  2390.                SUB     DI,8
  2391.                MOV     CX,5
  2392.                REPZ    CMPSB
  2393. S3 LABEL BYTE
  2394.                JA      SWAP                    ;If above, swap.
  2395.                JNZ     NO_SWITCH
  2396.                ADD     SI,10                   ;Else, adjust and do meridian.
  2397.                ADD     DI,10
  2398.                CMPSB
  2399. S4 LABEL BYTE
  2400.                JA      SWAP                    ;If above, swap.
  2401.                JNZ     NO_SWITCH
  2402.                SUB     SI,6                    ;Else, adjust and do time.
  2403.                SUB     DI,6
  2404.                MOV     CX,5
  2405.                CMP     WORD PTR [SI],3231H     ;Is it special case "12:"?
  2406.                JZ      CK_MERIDIAN             ;If yes, see if same.
  2407.                CMP     WORD PTR [DI],3231H     ;Is destination "12:"?
  2408.                JNZ     DATE_END                ;If no, normal compare.
  2409. CK_MERIDIAN:   CMPSB                           ;Are both "12:"?
  2410.  
  2411. S5 LABEL BYTE
  2412.                JB      LONG_JMP                ;Swap
  2413. S6 LABEL BYTE
  2414.                JA      NO_SWITCH
  2415.  
  2416.                CMPSB
  2417. S7 LABEL BYTE
  2418.                JB      LONG_JMP
  2419. S8 LABEL BYTE
  2420.                JA      NO_SWITCH
  2421.  
  2422.                MOV     CX,3                    ;Else compare minutes.
  2423. DATE_END:      JMP     COMPARE
  2424. LONG_JMP:      JMP     SWAP
  2425.  
  2426. ;----------------------------------------------;
  2427. ; OUTPUT: CF=1 if illegal parameter.
  2428.  
  2429. PARSE:         MOV     SI,FILENAME
  2430.                CALL    CAPITALIZE
  2431. NEXT_PARSE:    CALL    PARSE_DELIMIT
  2432.                LODSB
  2433.                CMP     AL,CR
  2434.                JBE     PARSE_END1
  2435.  
  2436.                CMP     AL,"/"
  2437.                JNZ     NEXT_PARSE
  2438.                CALL    PARSE_DELIMIT
  2439.                LODSB
  2440.                CMP     AL,CR
  2441.                CLC
  2442.                JZ      PARSE_END
  2443.  
  2444. CK_SWITCH:     MOV     CX,SWITCH_LEN
  2445.                MOV     BX,CX
  2446.                MOV     DI,OFFSET SWITCH_CHARS
  2447.                MOV     DX,DI
  2448.                ADD     DX,CX
  2449.                REPNZ   SCASB
  2450.                JNZ     ILLEGAL
  2451.                SUB     BX,CX
  2452.                DEC     BX
  2453.                SHL     BX,1
  2454.                ADD     BX,DX
  2455.                CALL    [BX]                    ;Process the command.
  2456.                JC      ILLEGAL
  2457.                JMP     NEXT_PARSE
  2458.  
  2459. ILLEGAL:       MOV     DX,OFFSET ILLEGAL_PARAM
  2460.                STC
  2461.                JMP     SHORT PARSE_END
  2462.  
  2463. PARSE_END1:    CLC
  2464. PARSE_END:     RET
  2465.  
  2466. ;-----------------------------------------------------------------;
  2467. ; INPUT: SI -> string;  OUTPUT SI -> first non-white space or CR. ;
  2468. ;-----------------------------------------------------------------;
  2469. PARSE_DELIMIT: PUSH    AX
  2470. NEXT_DELIMIT:  LODSB                           ;Get a byte.
  2471.                OR      AL,AL
  2472.                JZ      LEADING_END2
  2473.                CMP     AL,CR
  2474.                JZ      LEADING_END2
  2475.                CMP     AL,SPACE                ;Is it a space char or below?
  2476.                JBE     NEXT_DELIMIT
  2477.                CMP     AL,COMMA                ;Or comma?
  2478.                JZ      NEXT_DELIMIT
  2479.                CMP     AL,";"                  ;Or semicolon?
  2480.                JZ      NEXT_DELIMIT            ;If yes, parse.
  2481. LEADING_END2:  DEC     SI                      ;Else, adjust pointer to
  2482.                POP     AX
  2483.                RET                             ; string start.
  2484.  
  2485. ;----------------------------------------------;
  2486. ; INPUT:  SI -> string;  SI preserved.         ;
  2487. ;----------------------------------------------;
  2488. CAPITALIZE:    PUSH    SI
  2489. NEXT_CAP:      LODSB
  2490.                CMP     AL,CR
  2491.                JZ      CAP_END
  2492.                OR      AL,AL
  2493.                JZ      CAP_END
  2494.                CMP     AL,"a"
  2495.                JB      NEXT_CAP
  2496.                CMP     AL,"z"
  2497.                JA      NEXT_CAP
  2498.                AND     BYTE PTR [SI - 1],5FH
  2499.                JMP     NEXT_CAP
  2500. CAP_END:       POP     SI
  2501.                RET
  2502.  
  2503. ;----------------------------------------------;
  2504. SW_PRIOR:      MOV     DATE_FLAG,PRIOR
  2505.                JMP     SHORT GET_THE_DATE
  2506.  
  2507. SW_AFTER:      MOV     DATE_FLAG,AFTER
  2508.  
  2509. GET_THE_DATE:  CALL    PARSE_DELIMIT
  2510.                CALL    GET_NUMBER              ;Get first number.
  2511.                JZ      BAD_PARAMETER           ;Was it a zero or no number?
  2512.                MOV     DH,BL                   ;If yes, exit, else store month.
  2513.                CALL    PARSE_DATE
  2514.                JC      BAD_PARAMETER
  2515.                CALL    GET_NUMBER              ;Get next number.
  2516.                JZ      BAD_PARAMETER           ;Was it zero?
  2517.                MOV     DL,BL                   ;If yes, exit, else store day.
  2518.                CALL    PARSE_DATE
  2519.                JC      BAD_PARAMETER
  2520.                CALL    GET_NUMBER              ;Get last number.
  2521.                JZ      BAD_PARAMETER           ;Was it zero?
  2522.                MOV     CX,BX                   ;If yes, exit, else store year.
  2523.                CALL    CONVERT_DATE            ;Convert decimal to compressed
  2524.                MOV     FILEDATE,DX             ; hex number and store.
  2525.                JMP     SHORT GOOD_SWITCH
  2526.  
  2527. BAD_PARAMETER: STC
  2528.                JMP     SHORT SWITCH_END
  2529.  
  2530. ;--------------;
  2531. PARSE_DATE:    LODSB
  2532.                CMP     AL,"/"
  2533.                JZ      DATE_END1
  2534.                CMP     AL,"-"
  2535.                JZ      DATE_END1
  2536.                DEC     SI
  2537.                STC
  2538.                JMP     SHORT DATE_END2
  2539.  
  2540. DATE_END1:     CLC
  2541. DATE_END2:     RET
  2542.  
  2543. ;--------------;
  2544. SW_MODIFIED:   CALL    PARSE_DELIMIT
  2545.                XOR     AL,AL
  2546.                CMP     BYTE PTR [SI],"-"
  2547.                JZ      STORE_MOD1
  2548.                MOV     AL,MODIFIED
  2549.                CMP     BYTE PTR [SI],"+"
  2550.                JNZ     STORE_MOD2
  2551. STORE_MOD1:    INC     SI
  2552. STORE_MOD2:    MOV     MODIFIED_TYPE,AL
  2553. MODIFIED_END:  JMP     SHORT GOOD_SWITCH
  2554.  
  2555. ;--------------;
  2556. SW_HIDDEN:     OR      ATTR,HIDDEN
  2557.                JMP     SHORT GOOD_SWITCH
  2558.  
  2559. ;--------------;
  2560. SW_READ_ONLY:  OR      ATTR,READ_ONLY
  2561.                JMP     SHORT GOOD_SWITCH
  2562.  
  2563. ;--------------;
  2564. SW_WORDSTAR:   MOV     WORDSTAR_MASK,7FH
  2565.                JMP     SHORT GOOD_SWITCH
  2566.  
  2567. ;--------------;
  2568. SW_NAME:       MOV     SORT_INDEX,NAME_SORT
  2569.                JMP     SHORT GOOD_SWITCH
  2570.  
  2571. ;--------------;
  2572. SW_EXT:        MOV     SORT_INDEX,EXT_SORT
  2573.                JMP     SHORT GOOD_SWITCH
  2574.  
  2575. ;--------------;
  2576. SW_SIZE:       MOV     SORT_INDEX,SIZE_SORT
  2577.                JMP     SHORT GOOD_SWITCH
  2578.  
  2579. ;--------------;
  2580. SW_DATE:       MOV     SORT_INDEX,DATE_SORT
  2581.                JMP     SHORT GOOD_SWITCH
  2582.  
  2583. ;--------------;
  2584. SW_ORIGINAL:   MOV     SORT_INDEX,NO_SORT
  2585.                JMP     SHORT GOOD_SWITCH
  2586.  
  2587. ;--------------;
  2588. SW_FORMAT:     MOV     SORT_ORDER,DESCEND
  2589. FORMAT_END:    JMP     SHORT GOOD_SWITCH
  2590.  
  2591. GOOD_SWITCH:   CLC
  2592. SWITCH_END:    RET
  2593.  
  2594. ;----------------------------------------------;
  2595. ; INPUT: SI -> ASCII number.
  2596.  
  2597. GET_NUMBER     PROC    NEAR
  2598.  
  2599.                XOR     BX,BX                   ;Start with zero.
  2600. NEXT_NUMBER:   LODSB
  2601.                MOV     CL,10
  2602.                XOR     AH,AH                   ;Zero in high half.
  2603.                CMP     AL,CR                   ;Is byte a carriage return?
  2604.                JZ      NUMBER_END              ;If yes, done.
  2605.                CMP     AL,"0"                  ;Is byte a number?
  2606.                JB      NUMBER_END
  2607.                CMP     AL,"9"
  2608.                JA      NUMBER_END              ;If no, done.
  2609.                SUB     AL,"0"                  ;Else, convert to hex.
  2610.                XCHG    AX,BX                   ;Store in BX.
  2611.                MUL     CL                      ;Multiply accumulated by 10.
  2612.                ADD     BX,AX                   ;Add new number.
  2613.                JMP     SHORT NEXT_NUMBER
  2614.  
  2615. NUMBER_END:    DEC     SI                      ;Adjust pointer to delimiter.
  2616.                OR      BX,BX                   ;Set zero flag if results zero.
  2617.                RET
  2618.  
  2619. GET_NUMBER     ENDP
  2620.  
  2621. ;---------------------------------------------------;
  2622. ; INPUT                                             ;
  2623. ;   CX = Year  (1980 - 2099)                        ;
  2624. ;   DH = Month (1 - 12)                             ;
  2625. ;   DL = Day   (1 - 31)                             ;
  2626. ;                                                   ;
  2627. ; OUTPUT                                            ;
  2628. ;   DX = compressed date in directory entry format. ;
  2629. ;                                                   ;
  2630. ;        <     DH      > <     DL      >            ;
  2631. ;        y y y y y y y m m m m d d d d d            ;
  2632. ;                                                   ;
  2633. ;              y = year  (0 - 119)                  ;
  2634. ;              m = month (1 - 12)                   ;
  2635. ;              d = day   (1 - 31)                   ;
  2636. ;                                                   ;
  2637. ;   BX, CX destroyed.                               ;
  2638. ;---------------------------------------------------;
  2639.  
  2640. CONVERT_DATE   PROC    NEAR
  2641.  
  2642.                SUB     CX,80                   ;Compress year.
  2643.                CMP     CX,1900                 ;Did user abbreviate year?
  2644.                JB      SAVE_MONTH              ;If yes, OK.
  2645.                SUB     CX,1900                 ;Else, subtract century part.
  2646. SAVE_MONTH:    MOV     BL,DH                   ;Store month in BL.
  2647.                XOR     BH,BH                   ;Zero in high half.
  2648.                SHL     CL,1                    ;Right justify year.
  2649.                MOV     DH,CL                   ;Store in DH.
  2650.                MOV     CL,5                    ;Shift month left 5 bits.
  2651.                SHL     BX,CL
  2652.                OR      DX,BX                   ;Add year and month to days.
  2653.                RET
  2654.  
  2655. CONVERT_DATE   ENDP
  2656.  
  2657. ;----------------------------------------------;
  2658. VIDEO_SETUP:   PUSH    ES
  2659.                MOV     AX,500H                 ;Make sure active page is zero.
  2660.                INT     10H
  2661.                MOV     AX,40H                  ;Point to the ROM BIOS data area
  2662.                MOV     ES,AX
  2663.                MOV     AX,ES:CRT_COLS
  2664.                MOV     COLUMNS,AX
  2665.                SHL     AX,1
  2666.                MOV     CRT_WIDTH,AX
  2667.                MOV     AX,ES:[4EH]
  2668.                MOV     CRT_START,AX
  2669.  
  2670.                MOV     AX,ES:[63H]
  2671.                ADD     AX,6
  2672.                MOV     CX,0B000H
  2673.                CMP     AX,3BAH
  2674.                JZ      STORE_SEG
  2675.                ADD     CX,800H
  2676. STORE_SEG:     MOV     STATUS_REG,AX
  2677.                MOV     VIDEO_SEG,CX
  2678.  
  2679.                MOV     SI,OFFSET MONO_ATTR
  2680.                MOV     AL,ES:CRT_MODE          ;Retrieve current video mode.
  2681.                CMP     AL,7                    ;Is it mono mode?
  2682.                JZ      GET_ROWS                ;If yes, continue.
  2683.                CMP     AL,2                    ;Is it BW80?
  2684.                JZ      GET_ROWS                ;If yes, continue.
  2685.                MOV     SI,OFFSET COLOR_ATTR
  2686.                CMP     AL,3                    ;Is it mode CO80?
  2687.                JZ      GET_ROWS                ;If yes, continue.
  2688.                MOV     AX,3                    ;Else, change video mode to CO80.
  2689.                INT     10H
  2690.  
  2691. GET_ROWS:      XOR     BH,BH
  2692.                MOV     DL,24
  2693.                MOV     AX,1130H
  2694.                INT     10H
  2695.                MOV     ROWS,DL                 ;Store rows.
  2696.                SUB     DL,3
  2697.                XOR     DH,DH
  2698.                MOV     LISTING_LEN,DX
  2699.  
  2700.                POP     ES
  2701.                MOV     DI,OFFSET COLOR
  2702.                MOV     CX,SIZE COLOR_ATTRIBS
  2703.                REP     MOVSB
  2704.  
  2705. ;----------------------------------------------;
  2706.  
  2707. DISPLAY_SETUP: CALL    CLS                     ;Clear screen.
  2708.  
  2709.                CMP     BORDER_FLAG,1
  2710.                JZ      DO_COPYRIGHT
  2711.                MOV     BL,COLOR.W              ;Turn on border.
  2712.                AND     BL,7
  2713.                XOR     BH,BH
  2714.                MOV     AH,0BH
  2715.                INT     10H
  2716.  
  2717. DO_COPYRIGHT:  XOR     AX,AX
  2718.                CALL    CALC_ADDR
  2719.                INC     DI
  2720.                INC     DI
  2721.                MOV     SI,OFFSET COPYRIGHT     ;Point to copyright message.
  2722.                MOV     BH,COLOR.B              ;Use header attribute.
  2723.                CALL    WRITE_STRING            ;And display it.
  2724.                RET
  2725.  
  2726. ;----------------------------------------------;
  2727. INIT_ZOOM:     MOV     AX,2
  2728.                CALL    CALC_ADDR
  2729.                MOV     LCOLUMN_START,DI
  2730.  
  2731.                MOV     AX,SIZE MARK + SIZE LIST_NAME + 1
  2732.                CMP     ZOOM_STATE,SHORT_NAME
  2733.                JZ      STORE_ZOOM
  2734.                MOV     AX,SIZE FILE_RECORD
  2735.                CMP     ZOOM_STATE,LONG_NAME
  2736.                JZ      STORE_ZOOM
  2737.                XOR     AX,AX
  2738.  
  2739. STORE_ZOOM:    MOV     LCOLUMN_LEN,AX
  2740.                MOV     BX,SIZE FILE_RECORD
  2741.                SUB     BX,AX
  2742.                MOV     LCOLUMN_BAL,BX
  2743.  
  2744.                OR      AX,AX
  2745.                JZ      GET_FILE_LEN
  2746.                INC     AX
  2747. GET_FILE_LEN:  MOV     BX,COLUMNS
  2748.                SUB     BX,AX
  2749.                MOV     FCOLUMN_LEN,BX
  2750.  
  2751.                SHL     AX,1
  2752.                ADD     DI,AX
  2753.                MOV     FCOLUMN_START,DI
  2754.  
  2755.                CMP     ZOOM_STATE,FULL_FILE
  2756.                JZ      INIT_ZOOM_END
  2757.                MOV     DI,FCOLUMN_START
  2758.                DEC     DI
  2759.                DEC     DI
  2760.                MOV     BH,COLOR.B
  2761.                MOV     BP,LISTING_LEN
  2762.                MOV     AL,SPACE
  2763. NEXT_DIVIDER:  PUSH    DI
  2764.                CALL    WRITE_SCREEN
  2765.                POP     DI
  2766.                ADD     DI,CRT_WIDTH
  2767.                DEC     BP
  2768.                JNZ     NEXT_DIVIDER
  2769.  
  2770. INIT_ZOOM_END: RET
  2771.  
  2772. ;----------------------------------------------;
  2773. DISPLAY_MENU:  MOV     AL,UP_ARROW
  2774.                MOV     AH,"A"
  2775.                CMP     SORT_ORDER,ASCEND
  2776.                JZ      STORE_SORT2
  2777.                MOV     AL,DOWN_ARROW
  2778.                MOV     AH,"D"
  2779.  
  2780. STORE_SORT2:   MOV     SORT_MENU1,AL
  2781.                MOV     SORT_MENU2,AH
  2782.  
  2783.                CALL    MENU_OFFSET
  2784.                PUSH    DI
  2785.                MOV     BH,COLOR.B
  2786.                MOV     SI,OFFSET MENU
  2787.                CALL    WRITE_STRING
  2788.                POP     DI
  2789.                ADD     DI,CRT_WIDTH
  2790.                CALL    WRITE_STRING
  2791.                CALL    HIDE_CURSOR
  2792. MENU_END:      RET
  2793.  
  2794. ;----------------------------------------------;
  2795. ; OUTPUT: CF=1 if Esc pressed; FILENAME -> filename.
  2796.  
  2797. ENTER_FILENAME DB      " Enter filespec: ",0
  2798. NAME_CURSOR    EQU     $ - ENTER_FILENAME
  2799. FILENAME_LEN   EQU     80 - NAME_CURSOR - 1
  2800.  
  2801. FILE_CURSOR    DW      ?
  2802.  
  2803. GET_NAME:      CALL    MENU_OFFSET
  2804.                ADD     DI,CRT_WIDTH
  2805.                MOV     BH,COLOR.B
  2806.                MOV     SI,OFFSET ENTER_FILENAME
  2807.                CALL    WRITE_STRING
  2808.  
  2809.                MOV     SI,81H
  2810.                MOV     FILE_CURSOR,SI
  2811.                MOV     DI,SI
  2812.                MOV     CX,FILENAME_LEN
  2813.                MOV     LINE_START,DI
  2814.                ADD     DI,CX
  2815.                MOV     LINE_END,DI
  2816.                MOV     DI,81H
  2817.                CALL    PARSE_DELIMIT
  2818.  
  2819. GET_END:       LODSB
  2820.                CMP     AL,"/"
  2821.                JZ      GOT_END3
  2822.                CMP     AL,SPACE
  2823.                JBE     GOT_END3
  2824.                STOSB
  2825.                JMP     GET_END
  2826.  
  2827. GOT_END3:      MOV     CX,LINE_END
  2828.                SUB     CX,DI
  2829.                INC     CX
  2830.                MOV     AL,SPACE
  2831.                REP     STOSB
  2832.                XOR     AL,AL
  2833.                STOSB
  2834.                MOV     AL,CR
  2835.                STOSB
  2836.  
  2837. NEXT_FILENAME: CALL    MENU_OFFSET
  2838.                ADD     DI,CRT_WIDTH
  2839.                ADD     DI,NAME_CURSOR * 2
  2840.                MOV     BH,COLOR.B
  2841.                MOV     SI,LINE_START
  2842.                CALL    WRITE_STRING
  2843.  
  2844.                MOV     DI,FILE_CURSOR
  2845.                MOV     DX,DI
  2846.                ADD     DL,NAME_CURSOR
  2847.                SUB     DX,LINE_START
  2848.                MOV     DH,ROWS
  2849.                CALL    SET_CURSOR
  2850.                CALL    EDITOR
  2851.                MOV     FILE_CURSOR,DI
  2852.                JC      GET_NAME_END
  2853.                CMP     AH,ENTER_SCAN
  2854.                JNZ     NEXT_FILENAME
  2855. GET_NAME_END:  RET
  2856.  
  2857. ;*************LINE EDITOR**********************;
  2858.  
  2859. LINE_START     DW      ?
  2860. LINE_END       DW      ?
  2861.  
  2862. ;INPUT: DI=buffer position; LINE_START, LINE_END.
  2863. ;OUTPUT: AL=char. AH=scan code. CY=1 if Esc pressed.
  2864.  
  2865. EDITOR:        CALL    GETKEY
  2866.                XCHG    AL,AH
  2867.                JNC     DO_EDIT
  2868.                JMP     EDITOR_END
  2869. DO_EDIT:       MOV     BX,DI
  2870.                MOV     DX,LINE_START
  2871.                MOV     CX,LINE_END
  2872.  
  2873.                CMP     AH,ENTER_SCAN
  2874.                JNZ     CK_RIGHT
  2875.                JMP     EDITOR_DONE
  2876.  
  2877. CK_RIGHT:      CMP     AX,RIGHT_SCAN SHL 8
  2878.                JNZ     CK_LEFT
  2879.                CMP     DI,CX
  2880.                JZ      EDITOR_DONE
  2881.                CMP     BYTE PTR [DI],SPACE
  2882.                JZ      EDITOR_DONE
  2883.                INC     DI
  2884.  
  2885. CK_LEFT:       CMP     AX,LEFT_SCAN SHL 8
  2886.                JNZ     CK_BS
  2887.                CMP     DI,DX
  2888.                JZ      EDITOR_DONE
  2889.                DEC     DI
  2890.  
  2891. CK_BS:         CMP     AH,BS_SCAN
  2892.                JNZ     CK_DEL
  2893.                CMP     DI,DX
  2894.                JZ      EDITOR_DONE
  2895.                DEC     DI
  2896.                CALL    CK_INSERT
  2897.                JNZ     DO_DEL
  2898.                MOV     BYTE PTR [DI],SPACE
  2899.                JMP     SHORT EDITOR_CHANGE
  2900.  
  2901. CK_DEL:        CMP     AX,DEL_SCAN SHL 8
  2902.                JNZ     CK_HOME
  2903. DO_DEL:        PUSH    DI
  2904.                MOV     SI,DI
  2905.                INC     SI
  2906.                DEC     CX
  2907.                SUB     CX,DI
  2908.                JS      DEL_END
  2909.                REP     MOVSB
  2910.                MOV     BYTE PTR [DI],SPACE
  2911. DEL_END:       POP     DI
  2912.                JMP     SHORT EDITOR_CHANGE
  2913.  
  2914. CK_HOME:       CMP     AX,HOME_SCAN SHL 8
  2915.                JNZ     CK_END2
  2916.                MOV     DI,DX
  2917.  
  2918. CK_END2:       CMP     AX,END_SCAN SHL 8
  2919.                JNZ     CK_ASCII
  2920. NEXT_CK_END2:  CMP     DI,CX
  2921.                JZ      EDITOR_DONE
  2922.                CMP     BYTE PTR [DI],SPACE
  2923.                JZ      EDITOR_DONE
  2924.                INC     DI
  2925.                JMP     NEXT_CK_END2
  2926.  
  2927. CK_ASCII:      CMP     AL,SPACE
  2928.                JB      EDITOR_DONE
  2929.                CMP     AL,127
  2930.                JA      EDITOR_DONE
  2931.                CMP     DI,LINE_END
  2932.                JAE     EDITOR_DONE
  2933.                CALL    CK_INSERT
  2934.                JNZ     DO_INSERT
  2935.                JMP     SHORT EDITOR_DONE1
  2936.  
  2937. DO_INSERT:     PUSH    DI
  2938.                DEC     CX
  2939.                MOV     DI,CX
  2940.                SUB     CX,BX
  2941.                JZ      EDITOR_DONE2
  2942.                MOV     SI,DI
  2943.                DEC     SI
  2944.                STD
  2945.                REP     MOVSB
  2946.                CLD
  2947. EDITOR_DONE2:  POP     DI
  2948. EDITOR_DONE1:  STOSB
  2949.  
  2950. EDITOR_CHANGE: ; MOV     MODIFY_FLAG,1
  2951. EDITOR_DONE:   CLC
  2952. EDITOR_END:    RET
  2953.  
  2954. ;--------------------------
  2955.  
  2956. CK_INSERT:     PUSH    DS
  2957.                MOV     DX,40H
  2958.                MOV     DS,DX
  2959.                MOV     DL,DS:[17H]
  2960.                TEST    DL,80H                  ;Insert
  2961.                POP     DS
  2962.                RET
  2963.  
  2964. ;----------------------------------------------;
  2965. ;INPUT: CX=char count; AX=character
  2966. REPEAT_CHAR:   PUSH    AX
  2967.                CALL    WRITE_SCREEN
  2968.                POP     AX
  2969.                LOOP    REPEAT_CHAR
  2970.                RET
  2971.  
  2972. ;----------------------------------------------;
  2973. ; INPUT: AX = Starting line; OUTPUT: DI = Video address.
  2974.  
  2975. CALC_ADDR:     MUL     CRT_WIDTH
  2976.                ADD     AX,CRT_START
  2977.                MOV     DI,AX
  2978.                RET
  2979.  
  2980. ;----------------------------------------------;
  2981. ; INPUT:  AL = character to write;  BH = attribute.
  2982.  
  2983. WRITE_SCREEN:  PUSH    ES
  2984.                MOV     ES,CS:VIDEO_SEG         ;Point to screen segment.
  2985.                MOV     DX,CS:STATUS_REG        ;Retrieve status register.
  2986.                MOV     BL,AL                   ;Store character in BL.
  2987.  
  2988. HORZ_RET:      IN      AL,DX                   ;Get status.
  2989.                RCR     AL,1                    ;Is it low?
  2990.                JC      HORZ_RET                ;If not, wait until it is.
  2991.                CLI                             ;No more interrupts.
  2992.  
  2993. HWAIT:         IN      AL,DX                   ;Get status.
  2994.                RCR     AL,1                    ;Is it high?
  2995.                JNC     HWAIT                   ;If no, wait until it is.
  2996.  
  2997.                MOV     AX,BX                   ;Retrieve character; now it's OK
  2998.                STOSW                           ; to write to screen buffer.
  2999.                STI                             ;Interrupts back on.
  3000.                POP     ES
  3001.                RET                             ;Return
  3002.  
  3003. ;----------------------------------------------;
  3004. ; INPUT:  ES=VIDEO_SEG; DX=STATUS_REG; AL=character to write;  BH=attribute.
  3005.  
  3006. WRITE_CHAR:    MOV     BL,AL                   ;Store character in BL.
  3007.  
  3008. HORZ_RET2:     IN      AL,DX                   ;Get status.
  3009.                RCR     AL,1                    ;Is it low?
  3010.                JC      HORZ_RET2               ;If not, wait until it is.
  3011.                CLI                             ;No more interrupts.
  3012.  
  3013. HWAIT2:        IN      AL,DX                   ;Get status.
  3014.                RCR     AL,1                    ;Is it high?
  3015.                JNC     HWAIT2                  ;If no, wait until it is.
  3016.  
  3017.                MOV     AX,BX                   ;Retrieve character; now it's OK
  3018.                STOSW                           ; to write to screen buffer.
  3019.                STI                             ;Interrupts back on.
  3020.                RET                             ;Return
  3021.  
  3022. ;----------------------------------------------;
  3023. ; INPUT:  SI -> to string to display;  DI -> where to display it.
  3024. ;   Entry point is WRITE_STRING.
  3025.  
  3026. WRITE_IT:      CALL    WRITE_SCREEN            ;Write a character.
  3027. WRITE_STRING:  LODSB                           ;Retrieve a character.
  3028.                CMP     AL,CR                   ;Keep writing until a carriage
  3029.                JA      WRITE_IT                ; return or zero encountered.
  3030.                RET
  3031.  
  3032. ;----------------------------------------------;
  3033. CLEAR_MENU:    CALL    MENU_OFFSET             ;Calculate menu screen offset.
  3034.                PUSH    DI
  3035.                MOV     BH,COLOR.B              ;Menu attribute.
  3036.                MOV     CX,CRT_WIDTH            ;Blank out the two lines of menu.
  3037. NEXT_MENU:     MOV     AL,SPACE
  3038.                CALL    WRITE_SCREEN
  3039.                LOOP    NEXT_MENU
  3040.                POP     DI
  3041.                RET
  3042.  
  3043. ;----------------------------------------;
  3044. ; OUTPUT: DI -> Screen offset for menu.  ;
  3045. ;----------------------------------------;
  3046. MENU_OFFSET:   MOV     AL,ROWS
  3047.                DEC     AL
  3048.                XOR     AH,AH
  3049.                CALL    CALC_ADDR
  3050.                RET
  3051.  
  3052. ;----------------------------------------------;
  3053. CLS:           MOV     BH,COLOR.B              ;Normal attribute.
  3054. CLS2:          XOR     CX,CX                   ;Top left corner.
  3055.                MOV     DL,BYTE PTR COLUMNS
  3056.                DEC     DL
  3057.                MOV     DH,ROWS
  3058.                MOV     AX,600H                 ;Scroll active page.
  3059.                PUSH    BP
  3060.                INT     10H
  3061.                POP     BP
  3062.                RET
  3063.  
  3064. ;----------------------------------------------;
  3065. CLOSE_SCREEN:  PUSH    AX
  3066.                MOV     BH,SCREEN_COLOR
  3067.                CALL    CLS2
  3068.  
  3069.                CMP     BORDER_FLAG,1
  3070.                JZ      PLACE_CURSOR
  3071.                XOR     BX,BX
  3072.                MOV     AH,0BH
  3073.                INT     10H
  3074.  
  3075. PLACE_CURSOR:  XOR     DX,DX
  3076.                CALL    SET_CURSOR
  3077.                POP     AX
  3078.                RET
  3079.  
  3080. ;----------------------------------------------;
  3081. BEEP:          MOV     BX,NOTE                 ;Tone frequency divisor.
  3082.                MOV     DX,12H
  3083.                XOR     AX,AX
  3084.                DIV     BX
  3085.                MOV     BX,AX                   ;8253 countdown.
  3086.  
  3087.                CALL    DELAY                   ;Wait till clock rolls over.
  3088.  
  3089.                MOV     AL,0B6H                 ;Channel 2 speaker functions.
  3090.                OUT     43H,AL                  ;8253 Mode Control.
  3091.                JMP     $+2                     ;IO delay.
  3092.                MOV     AX,BX                   ;Retrieve countdown.
  3093.                OUT     42H,AL                  ;Channel 2 LSB.
  3094.                JMP     $+2
  3095.                MOV     AL,AH                   ;Channel 2 MSB.
  3096.                OUT     42H,AL
  3097.                IN      AL,61H                  ;Port B.
  3098.                OR      AL,3                    ;Turn on speaker.
  3099.                JMP     $+2
  3100.                OUT     61H,AL
  3101.  
  3102.                CALL    DELAY                   ;Delay one second.
  3103.                IN      AL,61H                  ;Get Port B again.
  3104.                AND     AL,NOT 3                ;Turn speaker off.
  3105.                JMP     $+2
  3106.                OUT     61H,AL
  3107.                RET                             ;Done.
  3108.  
  3109. ;-----------------------------;
  3110. DELAY:         PUSH    DS                      ;Preserve data segment.
  3111.                MOV     AX,40H                  ;Point to BIOS data segment.
  3112.                MOV     DS,AX
  3113.                MOV     AX,DS:[6CH]             ;Retrieve timer low.
  3114. NEXT_BEEP:     MOV     DX,DS:[6CH]             ;Retrieve timer low.
  3115.                CMP     DX,AX                   ;Have we timed out?
  3116.                JZ      NEXT_BEEP               ;If not, wait until second up.
  3117.                POP     DS                      ;Restore data segment.
  3118.                RET
  3119.  
  3120. ;----------------------------------------------;
  3121. ; INPUT: SI-> DIR storage.
  3122.  
  3123. GET_DIR:       MOV     BYTE PTR [SI],"\"       ;DOS doesn't preface directory
  3124.                INC     SI                      ; with slash so we must.
  3125.                XOR     DL,DL
  3126.                MOV     AH,47H                  ;Get current directory.
  3127.                INT     21H
  3128.                RET
  3129.  
  3130. ;----------------------------------------------;
  3131. HIDE_CURSOR:   MOV     DH,ROWS                 ;Retrieve CRT rows.
  3132.                INC     DH                      ;Move one line below off screen.
  3133.                XOR     DL,DL                   ;Column zero.
  3134.  
  3135. SET_CURSOR:    PUSH    BX
  3136.                XOR     BH,BH                   ;Page zero.
  3137.                MOV     AH,2                    ;Set cursor position.
  3138.                INT     10H
  3139.                POP     BX
  3140.                RET
  3141.  
  3142. ;----------------------------------------------;
  3143. RESTORE_DIR:   MOV     DX,OFFSET CURRENT_DIR
  3144.  
  3145. ;----------------------------------------------;
  3146. CHANGE_DIR:    MOV     AH,3BH                  ;Change current directory.
  3147.                INT     21H
  3148.                RET
  3149.  
  3150. ;----------------------------------------------;
  3151. ; INPUT:  AL=Scan code; AH=Char; DI -> Valid scan codes table; CX = Table length
  3152. ; OUTPUT: AL=Scan code; AH=Char.
  3153.  
  3154. DISPATCH:      PUSH    AX
  3155.                MOV     BX,CX
  3156.                MOV     DX,DI
  3157.                ADD     DX,CX
  3158.                REPNZ   SCASB
  3159.                JNZ     DISPATCH_END
  3160.  
  3161. GOT_DISPATCH:  SUB     BX,CX
  3162.                DEC     BX
  3163.                SHL     BX,1
  3164.                ADD     BX,DX
  3165.                CALL    GET_PARAMS
  3166.                CALL    [BX]                    ;Process the command.
  3167. DISPATCH_END:  POP     AX
  3168.                RET
  3169.  
  3170. ;----------------------------------------------;
  3171.  
  3172. GET_PARAMS:    MOV     AX,SIZE FILE_RECORD
  3173.                MUL     LISTING_LEN
  3174.                MOV     BP,BAR_ADDR
  3175.                MOV     DX,LISTING_ADDR
  3176.                MOV     CX,LAST_ADDR
  3177. PARAMS_END:    RET
  3178.  
  3179. ;----------------------------------------------;
  3180.  
  3181. GETKEY:        TEST    KBD_STATUS,80H
  3182.                JNZ     KEY_CLEAR
  3183.                CALL    CK_KEY
  3184.                JNZ     GETKEY2
  3185.                JMP     GETKEY
  3186.  
  3187. KEY_CLEAR:     CALL    CLEAR_KEY
  3188.                MOV     KBD_STATUS,0
  3189.                CMP     FILE_CURRENT,TRUE
  3190.                JZ      GETKEY
  3191.                CALL    DISP_FILE
  3192.                JMP     GETKEY
  3193.  
  3194. GETKEY2:       XOR     AH,AH                   ;Wait for next keyboard input.
  3195.                INT     16H
  3196.                XCHG    AH,AL
  3197.                CMP     AL,ESC_SCAN
  3198.                STC
  3199.                JZ      GETKEY_END
  3200.                CLC
  3201. GETKEY_END:    RET
  3202.  
  3203. CK_KEY:        MOV     AH,1                    ;Is there a keystroke available.
  3204.                INT     16H
  3205.                RET
  3206.  
  3207. CLEAR_IT:      XOR     AH,AH
  3208.                INT     16H                     ;Read keystrokes until buffer
  3209. CLEAR_KEY:     CALL    CK_KEY                  ; empty.
  3210.                JNZ     CLEAR_IT
  3211.                RET
  3212.  
  3213. ;----------------------------------------------;
  3214.  
  3215. WRITE_TTY:     MOV     AH,0EH
  3216.                INT     10H
  3217.                RET
  3218.  
  3219. ;----------------------------------------------;
  3220. PRINT_STRING:  MOV     AH,9                    ;Print string via DOS.
  3221.                INT     21H
  3222.                RET
  3223.  
  3224. ;----------------------------------------------;
  3225. OLD9           DW      ?,?
  3226.  
  3227. INSTALL_9:     PUSH    ES
  3228.                MOV     AX,3509H                ;INT 9
  3229.                INT     21H
  3230.                MOV     OLD9[0],BX
  3231.                MOV     OLD9[2],ES
  3232.                MOV     DX,OFFSET INT_9         ;Install new interrupt.
  3233.                MOV     AX,2509H
  3234.                INT     21H
  3235.                POP     ES
  3236.                RET
  3237.  
  3238. ;----------------------------------------------;
  3239. UNINSTALL_9:   PUSH    DS
  3240.                MOV     DX,OLD9[0]              ;Restore old INT 9.
  3241.                MOV     DS,OLD9[2]
  3242.                MOV     AX,2509H
  3243.                INT     21H
  3244.                POP     DS
  3245.                RET
  3246.  
  3247. ;----------------------------------------------;
  3248. INSTALL_24:    MOV     DX,OFFSET INT_24        ;Install new interrupt.
  3249.                MOV     AX,2524H
  3250.                INT     21H
  3251.                RET
  3252.  
  3253. EVEN
  3254. STACK_POINTER  =       $ + 256
  3255.  
  3256.  
  3257. _TEXT          ENDS
  3258.                END     START
  3259.